可能过早地离开递归?

时间:2011-12-11 08:17:21

标签: c++ recursion

我当前的递归函数在某种程度上起作用,但是当它回到堆栈时会自行消失。

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时存储了正确的路径,但在备份的路上将其删除。

有没有办法逃脱它,比如休息。

没有任何例外

5 个答案:

答案 0 :(得分:17)

有一种方法可以使用异常退出递归,但我不推荐它。相反,修改您的函数以返回一个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;
}

答案 1 :(得分:0)

例外(或C longjmp)是离开递归的方法。您可能还有一个static boolean leaveme;标记,并使用if (leaveme) return;等启动您的功能。

但是longjmp与本地帧中的值的析构函数不能很好地协作(虽然例外)。

答案 2 :(得分:0)

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

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

或者表示递归状态的全局标志,如果我们可以,则返回。否则递归应该返回。

答案 3 :(得分:0)

目前

//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;

答案 4 :(得分:0)

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);
    }
}