在C ++中编写递归函数的最佳方法?

时间:2010-06-18 14:24:53

标签: c++ algorithm function recursion

问题
我想知道这是否是一种实现变深度递归的可行方法,这样我就可以在每一步运行一个函数,并为描述问题提供更好的/其他解决方案。
描述
假设我希望有一个以模式
填充数组的函数 x,y,x,y,x,y其中x和y是由某些算法定义的变量
x,y,z,x,y,z其中x,y和z是由同一算法定义的变量。

对于所有数量的变量,这应该继续。这是实现它的可行方法吗?

void recurse_n(int n)
{
    while(n > 0)
    {
        --n;
        recurse_n(n);
        n = 0;
        // Use algorithm here
    }
}

编辑:删除了之前提到的错误返回类型。 Brainfart。

6 个答案:

答案 0 :(得分:6)

因此,根据您的评论,您想知道设置递归函数的最佳方法。你所做的将会起作用,但它是令人费解的,有点令人困惑。我要做的是简化它:

void recurse_n(int n) {
    if (n <= 0) {
        // Break-out condition
        return;
    }

    --n;
    recurse_n(n);

    // Your algorithm stuff here.
}

这样可以更容易地看到发生了什么。我要补充的一件事是你可能想在调用recurse_n之前做一些算法,但这完全取决于你的算法在做什么。

如果你考虑它,我写它的方式,它会递归,直到n小于或等于0才能进行任何算法工作。可能是你想要算法工作然后递归。

答案 1 :(得分:4)

首先,使用std :: vector和一个循环(我假设x(),y()和z()返回你需要的int,你也可以使用一个向量存储值):

void fill( std::vector<int> &vec, std::vector<int> &values )
{
    size_t nValues = values.size();
    size_t sz = vec.size();
    for( size_t i=0; i<sz; i=i+nValues )
    {
        for( size_t j=0; j<nValues; ++j )
        {
            vec[i] = values[j];
        }
    }
}

int main()
{
    std::vector<int> vec;
    std::vector<int> values;
    /* fill values vector here */
    vec.resize( 512 ); // (arbitraty) size you need
    fill( vec, values );

    return 0;
}

这是更多的C ++ - ish并且比递归函数快得多。另外:存储x,y和z值,以便相应的算法只执行一次。

答案 2 :(得分:2)

我不认为这是一种可行的方法,因为:让T(n)表示函数的运行时间(取决于输入参数n)。

基本案例n=0产生以下运行时间:T(0)=c,即一些常量运行时c

现在,您可以为n>0T(n)=sum(i = 0 to n-1: T(i))的运行时间定义递归公式。

如果你解决这个等式,就得到T(n)=O(2^n),这意味着你的算法是指数的,这意味着它在实践中不易处理。

答案 3 :(得分:1)

我对这个问题有点不清楚,但听起来你有一组变量a, b, c, ..., z并且你想填充一个数组,因此它包含a, b, c, ..., z, a, b, c, ..., z, a, ...。如果是这样,将源变量放在它们自己的一次通过数组a, b, c, ..., zmemcpy中它可能是最简单的,直到它被填充

#define NUM 3
int a, b, c; // source variables
void fill(int* arr, unsigned int size) {
    int src[] = {a, b, c};
    unsigned int i;
    for(i = 0; i < size / NUM; i++)
        memcpy(arr + (NUM * i), src, sizeof(int) * NUM);
    memcpy(arr + (NUM * i), src, sizeof(int) * (size % NUM));
}

答案 4 :(得分:1)

JimDaniel是对的,这里的递归是一种矫枉过正。你没有从函数返回任何东西,看起来你只是使用“n”来控制递归的数量。使用简单的for循环会更清晰+更有效。

答案 5 :(得分:1)

如果您的算法满足以下要求,则填充数组的递归是有效的(即使是最好的)选项:

  1. 位置n的值取决于至少某些值之前的值
  2. 在没有首先确定它所依赖的早期值的情况下,没有(已知)方法确定位置n的值。
  3. 符合这些要求的示例是fibonacci numbers。因为在没有先确定所有早期数字的情况下(尽管存在一些快捷方式),您无法确定第n个数字。

    一个不符合这些要求的例子是一个用索引的平方填充的数组,其中位置n的值只是n^2

    最后,我建议你根据DaveJohnston对你问题的答案中的模式重写你的功能。