【问题标题】:Creating a Recursive Function for Number Sequence为数列创建递归函数
【发布时间】:2016-11-29 04:30:58
【问题描述】:

我知道这是基本的 CS 知识,但我仍然无法理解在 for 循环上执行递归函数的想法。我仍然对递归的想法感到困惑,尤其是数字。假设有一个数字序列 3、11、27、59、123.... 我知道如何计算出数学递归序列,它只是 An = An-1 + (8*(n-1)),但是不要'真的不知道如何将其放入 C++ 递归函数中。

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

【问题讨论】:

    标签: c++ recursion


    【解决方案1】:

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

    递归部分处理最初的问题(在您的情况下,查找序列中的第 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上的一个非常好的视频

    【讨论】:

      【解决方案2】:

      所述函数的基本递归实现(您的序列的正确值为 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);
      }
      

      【讨论】:

        【解决方案3】:

        如果您的序列函数定义为: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,但这是个人喜好。注意:我没有测试这段代码,但希望你能明白。简而言之,一旦定义了序列函数,然后创建一个循环或程序函数来生成数字。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-11-01
          • 1970-01-01
          • 2017-07-08
          • 2021-04-18
          • 2010-11-21
          • 1970-01-01
          相关资源
          最近更新 更多