Tini
Tini

Reputation: 11

Variable number of nested loops with head and tail

I have these nested for loops:

void fun() {

    int n = 5;
    int c = 0;

    for (int i = 0; i < n; i++) {
        head_function(i, c);
        for (int j = 0; j < n; j++) {
            head_function(j, c);
            for (int w = 0; w < n; w++) {
                head_function(w, c);
                for (int x = 0; x < n; x++) {
                    head_function(x, c);

                    c++;
                    body(c);

                    tail_function(x, c);
                }
                tail_function(w, c);
            }
            tail_function(j, c);
        }
        tail_function(i, c);
    }
}

It doesn't really matter what the head and tail functions do, as long as they can keep track of their indices i, j, w, x.

What I want is to have an arbitrary number of nested for loops instead of just four.

The other solutions I found here didn't really work for me, because they did not include the head and tail functions, I guess.

Upvotes: 1

Views: 294

Answers (3)

markspace
markspace

Reputation: 11030

Here's a non-recursive version that iterates over a single array of loop indices.

You're code as a bit of a niggle in it: the innermost loop is different from the other loops in that only it calls body() and increments the general counter. I accounted for this by checking inside my loop for the "inner loop" which is indicated by the loop variable being 0.

I also changed your n from 5 to 3 (max), just to reduce the size of the output. The rest of the code I think is pretty straight forward.

public class Test {

    public static void main(String[] args) {
        System.out.println("\n Loop 1\n");
        loop( 1 );
        System.out.println("\n Loop 2\n");
        loop( 2 );
        System.out.println("\n Loop 3\n");
        loop( 3 );
    }

    public static void loop( int depth ) {
        int[] indices = new int[depth];
        final int max = 3;
        int count = 0;
        for( int x = 0; x < depth - 1; x++ )
            head( x, count );
        outer:
        for(;;) {
            for( int loop = 0; loop < indices.length; loop++ ) {
                if( indices[loop] < max ) {
                    head( indices[loop], count );
                    if( loop == 0 ) {
                        count++;
                        body( indices[loop], count );
                    }
                    tail( indices[loop], count );
                    indices[loop]++;
                    break;
                } else {
                    if( loop == indices.length - 1 ) break outer;
                    indices[loop] = 0;
                }
            }
        }
    }

    private static void head( int index, int counter ) {
        System.out.printf( "head index=%d count=%d%n", index, counter );
    }
    private static void body( int index, int counter ) {
        System.out.printf( "body index=%d count=%d%n", index, counter );
    }
    private static void tail( int index, int counter ) {
        System.out.printf( "tail index=%d count=%d%n", index, counter );
    }

}

Partial output (it gets rather long):

 Loop 1

head index=0 count=0
body index=0 count=1
tail index=0 count=1
head index=1 count=1
body index=1 count=2
tail index=1 count=2
head index=2 count=2
body index=2 count=3
tail index=2 count=3

Upvotes: 1

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 299118

Here's a skeleton to get you started. Feel free to add params and change signatures according to your needs.

public void doStuffRecursively(int nTimes){
    doIt(nTimes);
}

void doIt(int depth){
    if(depth==0)
        body();
    else{
        head(depth);
        doIt(depth-1);
        tail(depth);
    }
}

void body(){}

void head(int depth){}
void tail(int depth){}

Upvotes: 1

SamCle88
SamCle88

Reputation: 275

Since n seems to be always the same, you can try (c is now a private field, n is the number of the nested for loops):

private int c;

void loopAtDepth(int depth){
    if( depth == 0){
       c++;
       body(c);
    } else {
        for(int i = 0; i < n; i++){
            head_function(i, c);
            loopAtDepth(depth - 1)
            tail_function(i, c);
        }
    }
}

Upvotes: 0

Related Questions