【问题标题】:Please explain why my code caused a Stack Overflow Error请解释为什么我的代码导致堆栈溢出错误
【发布时间】:2020-02-17 02:07:33
【问题描述】:

代码如下:

public static int maxPathLengthHelper(int[][] paths, int x, int y){
    int maxLength = 0;
    if(x > 0 && paths[x-1][y] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x-1,y);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    if(y > 0 && paths[x][y-1] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x,y-1);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    if(x < paths.length - 1 && paths[x+1][y] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x+1,y);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    if(y < paths[0].length - 1 && paths[x][y+1] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x,y+1);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    return maxLength;
}

在改变y值的if语句中,会导致Stack Overflow错误,而改变x值的部分没有错误。我想知道为什么会这样;如果两者都错了,我会改变整个事情,但它只是在第二个和第四个 if 语句中堆栈溢出错误是由递归调用引起的。第一个和第三个 if 语句没有问题,我完全不知道它们有什么不同。

【问题讨论】:

  • 您的搜索一直在来回摆动。
  • 现在正是练习调试技能的完美时间,包括在您最喜欢的 IDE 调试器中运行此代码、设置断点,从而尝试隔离和识别错误。
  • 例如,请给一个(引用标志)desired behavior, a specific problem or error。此外,添加示例输入和输出。
  • 好的,我修好了,谢谢(编辑:我的意思是代码,我得到了我想要的答案)

标签: java recursion stack-overflow


【解决方案1】:

这是因为当您的代码从 0,0 移动到 1,0 时,它会再次检查 0,0 是否满足第一个 if 条件


public static int[][] visitedNodes;

public static void main(String args[]){
  // when you call the recursive method, also initiate the visitedNodes
   visitedNodes = new int[totalX][totalY];
   for(int i = 0; i < totalX; i++)
     for(int j = 0; j < totalY; i++)
        visitedNodes[i][j] = 0;
   maxPathLengthHelper(myPathList,0,0);
}

public static int maxPathLengthHelper(int[][] paths, int x, int y){
    int maxLength = 0;
    visitedNodes[x][y] = 1;
    if(x > 0 && visitedNodes[x-1][y] == 0 && paths[x-1][y] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x-1,y);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    if(y > 0 && visitedNodes[x][y-1] == 0  && paths[x][y-1] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x,y-1);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    if(x < paths.length - 1 && visitedNodes[x+1][y] == 0  && paths[x+1][y] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x+1,y);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    if(y < paths[0].length - 1 && visitedNodes[x][y+1] == 0  && paths[x][y+1] == 1){
        int currentLength = 1 + maxPathLengthHelper(paths,x,y+1);
        if(currentLength > maxLength){
            maxLength = currentLength;
        }
    }
    return maxLength;
}

【讨论】:

  • 这只会阻止后退,而不是循环行走,例如0,00,11,11,00,0
  • 哦.. 对.. 我猜你需要维护一组所有访问过的节点
  • 一个新的int 数组已经初始化为全零,因此分配0 值的双for 循环是多余的。
  • 哦,那是新的......谢谢@Andreas
猜你喜欢
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 2010-09-08
  • 2011-10-22
  • 2014-12-20
相关资源
最近更新 更多