为什么这是无限递归?

时间:2017-07-14 01:14:51

标签: c++ recursion

我编写了以下函数,以找出从起始单元格(0,0)到目标单元格(n,n)可以到达的路径数。我不能,因为我的生活,弄清楚为什么这是无限递归。

代码如下:

#include <iostream>

using namespace std;

int numOfPathsToDestUtil(int start, int end, int noOfPaths, int n) {
  cout<<"Start: "<<start<<" and end: "<<end<<"and n: "<<n<<"\n";
  if(start==end && start==n)
    return noOfPaths;

  if(end<start)
    return 0;

  numOfPathsToDestUtil(start+1, end, noOfPaths+1,n) + numOfPathsToDestUtil(start, end+1, noOfPaths+1,n);
}

int numOfPathsToDest( int n ) 
{
  cout<<"n is: "<<n<<"\n";
  return numOfPathsToDestUtil(0,0,0,n);
}

int main() {
  int ans = numOfPathsToDest(4);
  cout<<ans;

  return 0;
}

注意:我没有请求代码帮助(这样说,因为end<start之类的条件是特定于实现的。请让我理解为什么这个递归不会停止:

  

n是:4
  开始:0和结束:0和n:4
  开始:1和结束:0和n:4
  开始:0和结束:1和n:4
  开始:1和结束:1和n:4
  开始:2和结束:1和n:4
  开始:1和结束:2和n:4
  开始:2和结束:2和n:4
  开始:3和结束:2和n:4
  开始:2和结束:3和n:4
  开始:3和结束:3和n:4
  开始:4和结束:3和n:4
  开始:3和结束:4和n:4
  开始:4和结束:4和n:4 - &gt;我希望它停在这里作为start = end和start = n
  开始:3和结束:5和n:4
  开始:4和结束:5和n:4
  开始:5和结束:5和n:4
  开始:6,结束:5和n:4
  开始:5和结束:6和n:4
  开始:6,结束:6和n:4

非常感谢你!

2 个答案:

答案 0 :(得分:2)

让我们给你的电话打上标签

numOfPathsToDestUtil(0,0,0,n) # original (O)
numOfPathsToDestUtil(start+1, end, noOfPaths+1,n) # first-recursive (FR)
numOfPathsToDestUtil(start, end+1, noOfPaths+1,n) # second-recursive (SR)

你的输出:

n is: 4 
Start: 0 and end: 0and n: 4        # O - numOfPathsToDestUtil(0,0,0,4)
Start: 1 and end: 0and n: 4        # FR -  numOfPathsToDestUtil(0+1,0,0,4)
Start: 0 and end: 1and n: 4        # SR - numOfPathsToDestUtil(0,0+1,0,4)
Start: 1 and end: 1and n: 4        # SR -> FR
Start: 2 and end: 1and n: 4        # SR -> FR -> FR
Start: 1 and end: 2and n: 4        # SR -> FR -> SR
Start: 2 and end: 2and n: 4        # SR -> FR -> SR -> FR
Start: 3 and end: 2and n: 4        # SR -> FR -> SR -> FR -> FR
Start: 2 and end: 3and n: 4        # SR -> FR -> SR -> FR -> SR
Start: 3 and end: 3and n: 4        # SR -> FR -> SR -> FR -> SR -> FR
Start: 4 and end: 3and n: 4        # SR -> FR -> SR -> FR -> SR -> FR -> FR
Start: 3 and end: 4and n: 4        # SR -> FR -> SR -> FR -> SR -> FR -> SR
Start: 4 and end: 4and n: 4        # SR -> FR -> SR -> FR -> SR -> FR -> SR -> FR (stops and returns value)
Start: 3 and end: 5and n: 4        # SR -> FR -> SR -> FR -> SR -> FR -> SR -> SR (never reaches where end==4 and n==4, keeps going and going)
Start: 4 and end: 5and n: 4
Start: 5 and end: 5and n: 4
Start: 6 and end: 5and n: 4
Start: 5 and end: 6and n: 4
Start: 6 and end: 6and n: 4

答案 1 :(得分:1)

如何调试:我建议你画一个调用树

  • 您缺少此行的退货声明

    numOfPathsToDestUtil(start + 1,end,noOfPaths + 1,n)+ numOfPathsToDestUtil(start,end + 1,noOfPaths + 1,n);

  • 仅考虑numOfPathsToDestUtil(start,end + 1,noOfPaths + 1,n)。 初始值(开始,结束)将是(0,0)然后调用=&gt; (0,1)=&gt;然后调用(0,2)=&gt; (0,3)=&gt;(0,4)=&gt;(0,5)...结束时没有终止约束。这部分将进入无限循环

  • 现在让我们考虑一下(希望下面的解释很容易理解)

Init(开始,结束,n,状态)

(0,0,4,calling)
=>(1,0,4, will end)+(0,1,4,calling)
=>(1,1,4,calling)+(0,2, 4,calling)
=>(2,1,4,will end)+(1,2,4,calling)+(0,2, 4,calling)
=>(1,2,4,calling)+(0,2, 4,calling)
=>(2,2,4,calling)+(1,3,4,calling) +(0,2,4,calling)

我认为你能够得出其余部分,并且它表明你的递归不会轻易脱离。

您需要修改约束以确保只有&#34;期望&#34;条件将继续递归。

  • 如果结束&gt;你会继续递归吗?
  • 如果开始==结束但是开始&lt; n会继续递归吗?

我不会列出所有。希望它为您提供良好的思考方向。