带有递归的函数导致堆栈溢出

Function with recursion is causing stack overflow

本文关键字:堆栈 栈溢出 函数 递归      更新时间:2023-10-16

我的函数有问题,该函数用于在1和0的迷宫中找到一条路径,如果它在该路径上或找到了出口,则返回true,如果迷宫无法解决,则返回false。每当我尝试检查变量的"-1s"时,我都会遇到堆栈溢出错误,但我的基本情况应该可以防止这种情况发生。有没有一种方法可以通过递归使用更少的堆栈空间?这是我的代码

bool Pathfinder::check(string& maze, stack<string>& path, int x, int y, int z) 
{int checking = 0;
if ((x == 4) && (y == 4) && (z == 4))
{
path.push(this->createCoords(x, y, z));
return true;
}
else
{
if ((x + 1) < 1 || (x + 1) > columns)
{
return false;
}
if ((y + 1) < 1 || (y + 1) > rows)
{
return false;
}
if ((z + 1) < 1 || (z + 1) > floors)
{
return false;
}
if ((x < 0) || (y < 0) || (z < 0))
{
return false;
}
if (this->getValue(maze, x, y, z) == 1)
{
this->setValue(maze, x, y, z, 2);
}
else
{
return false;
}
}

if (this->check(maze, path, x + 1, y, z) ||
this->check(maze, path, x, y + 1, z) ||
this->check(maze, path, x, y, z + 1))
{
checking++;
}
if (this->check(maze, path, x - 1, y, z) && checking == 1) //Overflow error comes from here
{
checking++;
}
if (this->check(maze, path, x, y - 1, z) && checking == 2)
{
checking++;
}
if (this->check(maze, path, x, y, z - 1) && checking == 3)
{
path.push(this->createCoords(x, y, z));
return true;
}
return false;
}

您不能使用"较少的堆栈空间",原因很简单,当所需的堆栈空间量为无穷大时,任何小于无穷大的东西仍然是无穷大的。这就是无穷大的含义。所示的算法在逻辑上有缺陷,显然会导致无限递归。让我们将其中一些递归调用标记如下:

if (this->check(maze, path, x + 1, y, z) ||   // A
this->check(maze, path, x, y + 1, z) ||   // B
this->check(maze, path, x, y, z + 1))     // C
{
checking++;
}
if (this->check(maze, path, x - 1, y, z) && checking == 1) // D
{
checking++;
}

checking的初始值为0。基于以上代码,我们可以得出以下结论。

1) 递归调用A总是发生。

2) 有一组坐标,A、B或C递归cals返回true

3) 当条件2)成立时,递归调用D总是发生。

因此,只要条件"2)"为真,就保证了无限递归。然后进行递归调用D的递归调用A在逻辑上是无限递归。

这是因为在导致条件2)为真的递归调用之前,递归调用A通过x+1。在递归调用中,条件"2)"计算为true,这将导致递归调用D.

但这会导致两个连续的嵌套递归调用,首先传递x+1,然后在第二个调用上传递x+1-1,具有相同的yz值。然后,第二个递归调用为xyz传递与其祖父母调用相同的值,这里没有任何东西可以阻止这种无限递归。

所显示的算法从根本上被破坏了。你需要弄清楚它为什么坏了,以及什么应该是正确的算法。这不能基于问题中有限的信息来回答,唯一可以琐碎地确定的是原因,以及为什么会发生无限递归的解释;这很明显。