可能过早地退出递归

Possible to leave recursion prematurely?

本文关键字:退出 递归      更新时间:2023-10-16

我当前的递归函数在一定程度上工作,但是当它返回堆栈时就会破坏自己。

void Graph::findPath( Room * curRoom )
{
if( curRoom -> myNumber == 0 )
{
    cout << "Outside.n";
    //Escape the recursion!
}
else
{
    curRoom -> visited = true;
    if( curRoom -> North -> visited == false )
    {   
        escapePath[ _index ] = "North";
        cout << "_index: " << _index << "n";
        ++_index;
        findPath( curRoom -> North );
        cout << "_index: " << _index << "n";
        escapePath[ _index ] = "";
        --_index;
    }
    if( curRoom -> East -> visited == false )
    {   
        escapePath[ _index ] = "East";
        cout << "_index: " << _index << "n";
        ++_index;
        findPath( curRoom -> East );
        cout << "_index: " << _index << "n";
        escapePath[ _index ] = "";
        --_index;
    }
    if( curRoom -> South -> visited == false )
    {   
        escapePath[ _index ] = "South";
        cout << "_index: " << _index << "n";
        ++_index;
        findPath( curRoom -> South );
        cout << "_index: " << _index << "n";
        escapePath[ _index ] = "";
        --_index;
    }
    if( curRoom -> West -> visited == false )
    {   
        escapePath[ _index ] = "West";
        cout << "_index: " << _index << "n";
        ++_index;
        findPath( curRoom -> West );
        cout << "_index: " << _index << "n";
        escapePath[ _index ] = "";
        --_index;
    }
}
}

为了节省阅读时间,这里的基本情况是找到0。否则它会尝试四个不同的基本方向,这是一个不同的编号房间。每次它进行一次移动,它都会将它所做的移动添加到外部数组中,每次它返回时,它都会从堆栈中删除该步骤。

我的问题是,当它找到0时,它有正确的路径存储,但在返回的过程中删除了它。

是否有方法可以转义,例如break

无gotos或异常

有一种使用异常退出递归的方法,但我不推荐这种方法。相反,修改您的函数以返回一个bool值,该bool值指示您是否找到了0,并修改您的逻辑,以便在找到0时从函数返回而不更改路径。下面是这个想法的说明:

bool Graph::findPath( Room * curRoom )
{
    if( curRoom -> myNumber == 0 )
    {
        cout << "Outside.n";
        //Escape the recursion!
        return true;
    }
    // ...
    if (findPath( curRoom -> North ))
        return true;
    // ...
    return false;
}

可能是longjmpsetjmp: http://www.cplusplus.com/reference/clibrary/csetjmp/。但是我不认为在c++中使用longjmp和setjmp是一个好主意。

最好是设置一些特殊的返回值,如果某个深度检测到它将立即返回,就像在c中一样。

或者一个全局标志,指示递归的状态,如果为true,则递归应该返回

//Escape the recursion!

我认为你可以将"答案"的副本保存到递归之外的字段中。如果函数已经在修改已经在递归之外的字段,那么也许可以将其设置为私有的辅助函数,其中包含一个附加的布尔参数,用于标记是否要退出。公共函数可以简单地调用这个,以抽象出在形参中有这样一个标志。

类似:

void Graph::findPath( Room * curRoom, bool done )

//Escape the recursion!
done = true;

findPath( curRoom -> North );
if (done) // new line here
    return;
cout << "_index: " << _index << "n";
escapePath[ _index ] = "";
--_index;

异常(或C longjmp)是离开递归的方式。你也可以有一个static boolean leaveme;标志,用if (leaveme) return;等来启动你的函数。

但是longjmp不能很好地处理局部帧中值的析构函数(而异常可以)。

bool flag = true;
int recursionFunction(parameters){
    if(flag){
        //do whatevere you wanna do
        if(condition satisfied){
            bool = false;
        }
    }
    else{
        return (whatever you want to return);
    }
}