为数字序列创建递归函数

时间:2016-11-29 04:30:58

标签: c++ recursion

我知道这是基本的CS知识,但我仍然无法掌握在for循环上执行递归函数的想法。我仍然对递归的想法感到困惑,尤其是数字。让我们说有一个数字序列3,11,27,59,123 ....我知道如何找出数学递归序列,只是An = An-1 +(8 *(n-1)),但是我真的知道如何把它放到C ++递归函数中。

有人可以概述为上述数字序列创建递归函数吗?

3 个答案:

答案 0 :(得分:5)

递归函数有两个"部分",基本情况和递归。基本情况是你的函数停止递归(并开始展开调用堆栈)。如果没有基础,函数会一直调用自己,直到堆栈溢出发生并且程序被操作系统终止。

递归部分采用初始问题(在您的情况下,在序列中查找第i个数字)并收缩它。这种情况发生在基本情况被击中之前。因此,为了找到序列中的第i个数字,让我们说第4个,你开始寻找第4个数字,但这取决于第3个,这取决于第2个,这取决于第一个。初始递归将问题从第4个数字缩小到第3个。

这是一个针对你的序列的递归函数的刺(不是完全测试过的)。

int recursive(int i) {
   // This is your base case, it prevents infinite recursion.
   if (i == 0) return 0; // Or whatever you base value is
   else {
     int sum = recursive(i-1) + 8 * (i-1);
     return sum;
   }
 }

很多时候,循环可以完成递归函数。但是有些函数需要递归。例如,Ackermann's Function。关于Computerphile

的非常好的视频

答案 1 :(得分:1)

所述函数的基本递归实现(序列的正确值为3,11,27,51,83,123,...顺便说一句):

int seq(int n)
{
    if (n <= 1)
        return 3;
    else
        return seq(n-1) + 8 * (n-1);
}

但是,这个实现不是尾递归的(因此它将使用堆栈,而迭代实现则不会)。我们可以通过引入累加器参数来编写尾递归版本:

int seq_r(int n, int acc)
{
    if (n <= 1)
        return acc;
    else
        return seq_r(n-1, acc + 8 * (n-1));
}

int seq(int n)
{
    return seq_r(n, 3);
}

或者,同样的实现,但是使用lambda表达式在函数中隐藏了seq_r:

#include <functional>

int seq(int n)
{
    std::function<int(int, int)> seq_r = [&] (int n, int acc) -> int {
        if (n <= 1)
            return acc;
        else
            return seq_r(n-1, acc + 8 * (n-1));
    };
    return seq_r(n, 3);
}

答案 2 :(得分:0)

如果您的序列函数定义为:A[n] = A[n-1] + 8*(n-1),那么您需要两件事。 1)用于保存数字序列的结构,以及2)用于产生这些数字的函数或循环。对于结构,我将使用std :: vector,循环或函数可以使用如下:

循环

#include <vector>

int main()
{
    std::vector<int> storage;

    // Seed the storage with a number since the sequence looks back.
    storage.push_back(3);

    // Define the maximum number count.
    int maxNum = 5;

    // Create the sequence by starting from n=1 since there are [n-1] terms.
    for(int n = 1; n <= maxNum; n++)
        storage.push_back(storage[n - 1] + 8*(n - 1));

    return 0;
}

功能

#include <vector>

std::vector<int> storage;

void DoSequence(int maxNum, int n = 0)
{
    // Check the limit.
    if(n > maxNum)
        return;

    // Check seeding condition if adding the first element,
    // otherwise run the equation.
    if(n == 0)
        storage.push_back(3);
    else
        storage.push_back(storage[n - 1] + 8*(n-1));

    // Call the same function.
    DoSequence(maxNum, n + 1);
}

int main()
{
    // Call the recursive function with upper limit (n=5).
    DoSequence(5);

    return 0;
}

还有其他方法可以实现详细信息,例如storage如何声明或处理,但这是个人偏好。注意:我没有测试这段代码,但希望你能得到这个想法。简而言之,一旦定义了序列函数,就创建一个循环或程序函数来生成数字。