Search code examples
arraysciteration

Variable number of nested array iterations in C


First, sorry if the title is not clear, but I don't know how to ask this properly.

Imagine I have an array of N elements, in this case 4:

#define ELEMENT_COUNT 4
int arr[ELEMENT_COUNT] = { 'a', 'b', 'c', 'd' };

If I wanted to get all the possible pairs formed with those elements (it doesn't matter if elements repeat), I would do something like this:

for (int i = 0; i < ELEMENT_COUNT; i++)
    for (int j = 0; j < ELEMENT_COUNT; j++)
        printf("%c %c\n", arr[i], arr[j]);

I would get the following output:

a a
a b
a c
a d
b a
b b
b c
b d
c a
c b
c c
c d
d a
d b
d c
d d

What if, instead of pairs, I wanted to print all the possible groups of 3? Of course, I could keep adding nested loops, but what if the number of elements in these "groups" is not known until runtime?

The desired output would be something like this:

// For groups of 3 (64 lines)
a a a
a a b
a a c
...

// For groups of 4 (256 lines)
a a a a
a a a b
a a a c
...

Solution

  • There are mutliple ways of doing so. Some using recursion, other managing the loop indexes through some additional structures.

    Here is the example of how I did it without recursion :

    #include <stdio.h>
    
    int main()
    {
        int n;
        scanf("%d", &n);
        n += 1;
        char arr[n];
        for(int i=0; i<n; ++i){
            arr[i] = 'a' + i;
        }
    
        int count[n];
        for(int i=0; i<n; ++i){
            count[i] = 0;
        }
    
        while( count[0] == 0 ){
            
            for(int i=1; i<n; ++i){
                printf("%c ", arr[count[i]]);
            }
            printf("\n");
    
            for(int i=n-1; i>=0; --i){
                if(count[i] == n-2){
                    count[i] = 0;
                } else {
                    count[i] += 1;
                    break;
                }
            }
        }
    }
    

    The code could easily be improved I guess, but it is functional at least. The idea is to iterate over all possible permutations, by saving the current element index for each 'rank' in another structure.

    I add an additional rank at the beginning to detect the overflow when all permutations have been processed.