В следующем примере с 5 циклами я могу получить каждый отдельный индекс для доступа к многомерному массиву. Есть ли способ для динамических систем, если я не знаю размерности массива, реализовать и рекурсивную функцию для доступа к массиву. => Рекурсивная реализация цикла for.
Например:
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}; //knownint 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++;
}
}
}
Например, вы можете создать вектор, содержащий все идентификаторы индекса, поэтому каждый в каждой рекурсии вы добавляете индекс в список перед вызовом рекурсивной функции, а затем удаляете его из списка.
Однако, вероятно, здесь лучше отказаться от идеи рекурсии, а вместо этого просто посмотреть на все перестановки, используя итеративную технику. Вот произвольное доказательство концепции, которая должна дать вам несколько идей:
#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;
}
Это, конечно, при условии, что вам действительно нужно знать индексы. Если вы просто пытаетесь обновить все счетчики, вы можете просто перейти от индекса 0 к индексу 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++;
Если вам не нужны индексы при прохождении массива, вы можете рассматривать его как простой массив. Используя пример известного размера выше:
int * ap = ****a;
int n = 1 * 2 * 3 * 1 * 5;
for (size_t i = 0; i < n; ++i)
*ap++ = counter++;
Я не уверен, что рекурсивная реализация купит вас. Это может взорвать стек, если массив большой.