[comp.lang.c] How to implement these loops ...

scm@cs.ed.ac.uk (Santa C Maria) (06/20/91)

This is probably a rather silly question. I would be glad, if you
can give me a hint. I want to implement a number of loops in this
manner:
   for ( i[0] = 0; i[0] < x[0]; ++i[0] ) {
      for ( i[1] = 0; i[1] < x[1]; ++i[1] ) {
	 ......
	 ......
	    for ( i[m-1] = 0; i[m-1] < x[m-1]; ++i[m-1] ) {
	       do_something_here();
	    }
	 ......
      }
   }

do_something_here() is thus executed x[0]*[x[1]* ... *x[m-1] times.
The problem is that m, x[0], ... x[m-1] all depend upon run-time
values. The question is how do I code this? 

Thanks in advance for your help.

pckim@unisql.UUCP (Pyung-Chul Kim) (06/21/91)

In article <12844@skye.cs.ed.ac.uk>, scm@cs.ed.ac.uk (Santa C Maria) writes:
>    for ( i[0] = 0; i[0] < x[0]; ++i[0] ) {
>       for ( i[1] = 0; i[1] < x[1]; ++i[1] ) {
> 	 ......
> 	    for ( i[m-1] = 0; i[m-1] < x[m-1]; ++i[m-1] ) {
> 	       do_something_here();
> 	    }
> 	 ......
>       }
>    }
> 
> The problem is that m, x[0], ... x[m-1] all depend upon run-time
> values. The question is how do I code this? 
> 


After determine m and allocate array x, and initialize elements of it,
and call the following recursive funtion foo(0):

/* assume m and x are global variables */
foo(j)
int     j;
{
	int     i;

	if(j == m-1) for(i = 0; i < x[j]; i++) do_something_here(i,j);
	else for(i = 0; i < x[j]; i++) foo(j+1);
}

Hope it helps
-- 
Pyung-Chul Kim

UniSQL, Inc.
9390 Research Blvd., Kaleido II, Suite 220, Austin, TX 78759
Internet: execu!sequoia!unisql!pckim@cs.utexas.edu
UUCP: {uunet, cs.utexas.edu!execu}!sequoia!unisql!pckim
TEL: (512)343-7297 Ext. 332
FAX: (512)343-7383

grue@cs.uq.oz.au (Frobozz) (06/21/91)

In <1377@unisql.UUCP> pckim@unisql.UUCP (Pyung-Chul Kim) writes:

]In article <12844@skye.cs.ed.ac.uk>, scm@cs.ed.ac.uk (Santa C Maria) writes:
]>    for ( i[0] = 0; i[0] < x[0]; ++i[0] ) {
]>       for ( i[1] = 0; i[1] < x[1]; ++i[1] ) {
]> 	 ......
]> 	    for ( i[m-1] = 0; i[m-1] < x[m-1]; ++i[m-1] ) {
]> 	       do_something_here();
]> 	    }
]> 	 ......
]>       }
]>    }
]> 
]> The problem is that m, x[0], ... x[m-1] all depend upon run-time
]> values. The question is how do I code this? 
]> 

]/* assume m and x are global variables */
]foo(j)
]int     j;
]{
]	int     i;
]	if(j == m-1) for(i = 0; i < x[j]; i++) do_something_here(i,j);
]	else for(i = 0; i < x[j]; i++) foo(j+1);
]}

I think that this can be done without a recursive function.  Something
like the following code should be able to do what is required.  I should
also mention that I haven't checked the following code for correctness,
so don't blame me when it don't work.

i[0] = 0;
for(j=0;j>=0;) {
  if(i[j] == x[j]) {	/* terminate a loop */
	j--;		/* to prev loop */
	i[j]++;		/* inc this counter */
  	continue;
  }
  if(j != m-1) {	/* not at deepest level of looping */
	j++;
	i[j] = 0;
	continue;
  }
  do_something();
  i[j]++;
}


An alternative would be to do something like:

	for(j=0,n=1;j<m;j++)	/* calc number of times through loop */
		n *= i[j];

	for(j=0;j<n;j++) {
		for(k=j,j1=m-1;j1>=0;j1--) {
			i[j1] = k % x[j1];
			k /= x[j1];
		}
		do_something();
	}

which first finds out how many times the loops will execute do_something and
then it sets up a loop that big.  At the start of every iteration, it
recalculates the loop index array i[].  This isn't a very efficient method,
but it does avoid the recursion that was present. There should be methods
to save recalculating the entire index array --- it should suffice to stop
recalculating when one of the elements doesn't change.
i.e. Change the line:
			i[j1] = k % x[j1];
to
			tmp = k % x[j1];
			if(i[j1] == tmp) break;
			i[j1] = tmp;


Again I haven't verified this code either.



        						Pauli
seeya

Paul Dale               | Internet/CSnet:            grue@cs.uq.oz.au
Dept of Computer Science| Bitnet:       grue%cs.uq.oz.au@uunet.uu.net
Uni of Qld              | JANET:           grue%cs.uq.oz.au@uk.ac.ukc
Australia, 4072         | EAN:                          grue@cs.uq.oz
                        | UUCP:           uunet!munnari!cs.uq.oz!grue
f4e6g4Qh4++             | JUNET:                     grue@cs.uq.oz.au

--

jos@and.nl (J. Horsmeier) (06/21/91)

In article <12844@skye.cs.ed.ac.uk> scm@lfcs.ed.ac.uk (Santa C Maria) writes:
>This is probably a rather silly question. I would be glad, if you
>can give me a hint. I want to implement a number of loops in this
>manner:
>   for ( i[0] = 0; i[0] < x[0]; ++i[0] ) {
>      for ( i[1] = 0; i[1] < x[1]; ++i[1] ) {
>	 ......
>	    for ( i[m-1] = 0; i[m-1] < x[m-1]; ++i[m-1] ) {
>	       do_something_here();
>	    }
[...]
>   }
>
>do_something_here() is thus executed x[0]*[x[1]* ... *x[m-1] times.
>The problem is that m, x[0], ... x[m-1] all depend upon run-time
>values. The question is how do I code this? 
>
>Thanks in advance for your help.


Hi there, try this one:


for (c= 0; c < m; i[c++]= 0);			/* All i[] to zero */

while (c != -1) {

	do_something_here();

	/* Next addition with carries */
	for (c= m-1; (c != -1)&&(i[c] >= x[c]-1); c--)
		i[c]= 0;

	/* Check on overflow */
	if (c != -1) 	
		i[c]++;

}

Hope this helps,


Jos


|O   J.A. Horsmeier AND Software B.V.        phone : +31 10 4367100   O|
|O                  Westersingel 106/108     fax   : +31 10 4367110   O|
|O                  3015 LD  Rotterdam NL    e-mail: jos@and.nl       O|