繁体   English   中英

递归函数导致堆栈溢出

[英]Function with recursion is causing stack overflow

我的函数有问题,用于在 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 递归校准返回true

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

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

这是因为在导致条件2)为真的递归调用之前,递归调用A通过x+1 并且在递归调用条件“2)”中评估为真,这导致递归调用 D。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM