How to implement these loops ...

Frobozz grue at cs.uq.oz.au
Fri Jun 21 12:49:32 AEST 1991


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

]In article <12844 at skye.cs.ed.ac.uk>, scm at 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 at cs.uq.oz.au
Dept of Computer Science| Bitnet:       grue%cs.uq.oz.au at uunet.uu.net
Uni of Qld              | JANET:           grue%cs.uq.oz.au at uk.ac.ukc
Australia, 4072         | EAN:                          grue at cs.uq.oz
                        | UUCP:           uunet!munnari!cs.uq.oz!grue
f4e6g4Qh4++             | JUNET:                     grue at cs.uq.oz.au

--



More information about the Comp.lang.c mailing list