2017-02-10 65 views
0

我有一个关于我所做的递归函数的问题。有一种方法,一旦我到达“return arraydenodes”行,我可以完全退出函数了吗?因为我使用visual studio执行了代码执行,并且一旦执行到达上述行,就会从while循环中返回到堆栈(或者我相信)到“else”中。正因为如此,path.Add线继续执行,给我一个不同的结果。这是代码。完全退出递归函数

private Node[] checkTheOtherDude(Node start, Node endpadre, Node end, Node previousNodeTemp) 
{ 

    //Debug.Log(previousNode); 
    while(endpadre != null && !stop) 
    { 

     if (!Physics.Linecast(end.transform.position, endpadre.transform.position)) // end y endpadre se ven? 
     { 
      previousNode = endpadre; 
      Node newParent = endpadre.padre; 

      checkTheOtherDude(start, newParent, end, previousNode); // chequear n y n padre padre 

     } 
     else 
     { 
      //previousNode = endpadre; 
      path.Add(end); 
      path.Add(previousNode); 
      end = endpadre; 
      Node newParent = end.padre; 
      checkTheOtherDude(start, newParent, endpadre, previousNode); 
     } 
    }  
     stop = true; 
     path.Add(end); 
     path.Add(start); 
     path.Reverse(); 
     arraydeNodes = path.ToArray(); 
     return arraydeNodes;     
} 

看来,我已经解决了这个问题,这个问题(或至少我认为)这是while条件,将其改为while (endpadre != null && !stop && endpadre != start)我错过了endpadre != start,使循环将结束右时结束节点与开始节点相同。

+3

如果你设计正确,它应该没有关系。如果遇到麻烦,递归方法做得太多(关注点分离)或者结构不正确。当最内部的调用退出时,它应该自然地返回到堆栈上方,即在该方法的正确返回结构内。 –

+1

当您在方法结束时递归退出时,您将不会退出,直到每次递归调用都达到它的退出点。这意味着遍历所有的东西。考虑将退出条件放在递归方法的开始 –

+0

因为我不确切知道函数应该做什么,所以在这种情况下可能会出错,但通常您要“返回”递归调用的结果。 – code11

回答

0

它是一路OK while循环后进入该代码会多次执行(与递归级别一样多)?
另外path.Reverse()将被多次调用,这是我不确定你真的想要的。

为了防止代码执行,你可以做这样的事情:

if (!stop) 
{ 
    stop = true; 
    path.Add(end); 
    path.Add(start); 
    path.Reverse(); 
    arraydeNodes = path.ToArray(); 
} 

return arraydeNodes;  

我打它一点点,我已经修改了你的代码。
试试这个:

private Node[] checkTheOtherDude(Node start, Node endpadre, Node end, Node previousNodeTemp) 
{ 
    if (endpadre == null) 
    { 
     path.Add(end); 
     path.Add(start); 
     path.Reverse(); 
     arraydeNodes = path.ToArray(); 
     return arraydeNodes; 
    } 
    else if (!Physics.Linecast(end.transform.position, endpadre.transform.position)) // end y endpadre se ven? 
    { 
     previousNode = endpadre; 
     Node newParent = endpadre.padre; 

     return checkTheOtherDude(start, newParent, end, previousNode); // chequear n y n padre padre 

    } 
    else 
    { 
     //previousNode = endpadre; 
     path.Add(end); 
     path.Add(previousNode); 
     end = endpadre; 
     Node newParent = end.padre; 
     return checkTheOtherDude(start, newParent, endpadre, previousNode); 
    }     
} 

尝试与实验数据(只有少数节点)运行此。然后在第一次点击后检查路径,然后调试第二次点击。你应该能够看到问题点。也许有无限递归(节点圆括号中的周期)

+0

每次点击时,代码都会运行并生成路径。第一次点击很好,第二次点击(在同一个程序运行期间)会引发堆栈溢出错误。 –

+0

查看我的修改后的答案代码 – tomassino

+0

仍然是一样的,我开始认为问题可能来自代码中的另一个地方,即使错误在这些行中说明。 –

0

是只是改变这两条线

checkTheOtherDude(start, newParent, end, previousNode); 
checkTheOtherDude(start, newParent, endpadre, previousNode); 

return checkTheOtherDude(start, newParent, end, previousNode); 
return checkTheOtherDude(start, newParent, endpadre, previousNode); 

这使它回到了

+0

每次点击时,代码都会运行并生成一条路径。第一次点击很好,第二次点击(在同一个程序运行期间)会引发堆栈溢出错误。 –

+0

@JackBauer你不应该让你的递归方法导致副作用。这是你的主要问题。你的递归方法应该计算一个值并将其返回,将它们需要的任何数据作为参数,并将其所有计算作为返回值返回。正如你所看到的,这个过程中的突变状态会造成巨大的混乱。 – Servy