【问题标题】:Recursive call instead of multiple for loop calls C++ [closed]递归调用而不是多个 for 循环调用 C++ [关闭]
【发布时间】:2013-05-21 21:21:07
【问题描述】:

在以下示例中,通过 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}; //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++;

【问题讨论】:

  • 天哪,你为什么需要这么多维度。
  • 你的结构实际上是一棵树。特殊情况,同一级别上的每个节点都有相同数量的子节点,因此解决问题的一种简单方法是使用一些树实现。使用像 a[1][2]... 这样的数组 - 你如何获得每级数组的元素数量?
  • 解决方案可以递归方式用于 2d 或 3d。?

标签: c++ multidimensional-array recursive-datastructures


【解决方案1】:

例如,您可以创建一个包含所有索引 ID 的向量,因此在每个递归中,您在调用递归函数之前将索引添加到列表中,然后将其从列表中删除。

但是,在这里放弃递归的想法可能是一个更好的主意,而只使用迭代技术查看所有排列。这是一个任意的概念证明,它应该会给你一些想法:

#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++;

【讨论】:

  • 如果它不是连续的并且索引从 for 循环中的 1 或非零值开始,您将无法获得正确的解决方案,例如: for (size_t r = 0; r
  • 指定了一个多维数组,该数组将在内存中连续,但如果它不是“数组”而是某种类型的列表,该属性无法保证,那么这是一个有效点。在这种情况下,我会建议使用迭代方法来获得维度排列。
【解决方案2】:

如果您在遍历数组时不需要索引,则可以将其视为简单数组。使用上面已知大小的示例:

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

我不确定递归实现会给你带来什么。如果数组很大,它可能会炸毁堆栈。

【讨论】:

    猜你喜欢
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2021-03-20
    • 2010-09-17
    • 2018-02-22
    相关资源
    最近更新 更多