0

On the following example, with 5 loops I am able to obtain each individual index to access into multi dimensional array. Is there any way for dynamic systems if I don't know the dimension of the array, implement and recursive function to access the array. => Recursively implementing the for loop.

For Example:

index[3] = 0; //=> because it is 3 dimenional all are zero

void recursiveIndexWalk(int i){
    a[0] = i;
    recursiveIndexWalk(a[1]);
    //on the inner last recursive call a[index[0]][index[1]][index[2]] = val;

}

main(){
    //my goal is to perform instead of 3 for loops => only one   recursive() called
    recursive(a[0]);
}

unsigned int dimensions = 3;    //known 
unsigned int dimension_length = { 1, 2, 3}; //known

int a[1][2][3];

int counter = 0;
for (size_t r = 0; r < 1; r++)           //|
   for (size_t q = 0; q < 2; q++)        //| 
      for (size_t p = 0; p < 4; p++)     //| =>recursiveForCall(indexArray) 
           a[i][j][k] = counter++;
alper
  • 2,919
  • 9
  • 53
  • 102
  • 5
    dear god, why do you need so many dimensions. – Syntactic Fructose May 21 '13 at 21:29
  • Your structure is actually a tree. Special case, where every node on the same level has the same amount of subnodes, so one easy way to solve the problem is to use some tree implementation. With array like a[1][2]... - how do you get the amount of elements per level of array? – mrówa May 21 '13 at 21:43
  • solution could be for 2d or 3d in a recursive way.? – alper May 21 '13 at 21:57

2 Answers2

2

You could, for example, create a vector containing all the index IDs, so each in each recurse you add the index to the list before calling the recursive function then remove it from the list after.

However, it's probably a better idea to forgo the recursion idea here and instead just look at all the permutations using an iterative technique. Here's an arbitrary proof of concept, which should give you some ideas:

#include <stdio.h>

const unsigned int dimensions = 3;
const unsigned int dimension_size[dimensions] = { 2, 4, 3 };

// Get first permutation.
inline void get_first_permutation( unsigned int * const permutation )
{
    for ( int i = 0; i < dimensions; ++i )
        permutation[i] = 0;
}

// Returns false when there are no more permutations.
inline bool next_permutation( unsigned int * const permutation )
{
    int on_index = dimensions - 1;
    while ( on_index >= 0 )
    {
        if ( permutation[on_index] >= dimension_size[on_index] )
        {
            permutation[on_index] = 0;
            --on_index;
        }
        else
        {
            ++permutation[on_index];
            return true;
        }
    }
    return false;
}

// Print out a permutation.
void print_permutation( const unsigned int * const permutation )
{
    printf( "[" );
    for ( int i = 0; i < dimensions; ++i )
        printf( "%4d", permutation[i] );
    printf( "]\n" );
}

int main( int argc, char ** argv )
{
    // Get first permutation.
    unsigned int permutation[dimensions];
    get_first_permutation( permutation );

    // Print all permutations.
    bool more_permutations = true;
    while ( more_permutations )
    {
        print_permutation( permutation );
        more_permutations = next_permutation( permutation );
    }

    return 0;
}

This is, of course, assuming you actually need to know the indices. If you're just trying to update all the counters you can just loop from index 0 to index dim_0*dim_1*...*dim_n

/* Defined somewhere. Don't know how this gets allocated but what-evs. :) */
unsigned int dimensions = 5;
unsigned int dimension_length = { 1, 2, 4, 7, 6 };
int * int_array = ...

/* Your loop code. */
unsigned int array_length = 0;
for ( unsigned int d = 0; d < dimensions; ++d )
    array_length += dimension_length[d];
int *array_pointer = int_array;
for ( unsigned int i = 0; i < array_length; ++i, ++array_pointer )
    array_pointer = counter++;
Anthony
  • 2,256
  • 2
  • 20
  • 36
  • you can't achive correct solution if it is not continuguos and indexes start from 1 or non-zero value in the for loop like: for (size_t r = 0; r < 1; r++) {for (size_t q = 1; q < 2; q++) { for (size_t p = 3; p < 4; p++) {... – alper May 21 '13 at 21:51
  • A multidimensional array was specified which will be contiguous in memory, but that's a valid point if it's not an "array" but rather some type of list where that property is not guaranteed. In which case I would advise the iterative approach to get the dimension permutations. – Anthony May 21 '13 at 21:54
0

If you don't need the indices as you traverse the array, you could treat it as a simple array. Using the known-size example above:

int * ap = ****a;
int n = 1 * 2 * 3 * 1 * 5;
for (size_t i = 0; i < n; ++i)
    *ap++ = counter++;

I'm not sure what a recursive implementation would buy you. It might blow the stack if the array is large.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365