我有一些代码在其实现中使用了递归。 profiler which I'm using递归函数调用效果不佳,所以我想将其重写为非递归。
目前的代码是这样的:
void Parse(Foo foo)
{
A()
for (;;)
{
B();
if (C())
return;
if (D())
{
Run();
}
E();
}
}
void Run()
{
X();
if (Y())
{
Parse();
}
Z();
}
以上是伪代码。字母 A、B、C、D、E、X、Y 和 Z 是方法,Parse() 和 Run() 也是。为简单起见,我省略了各种参数和对象取消引用(例如,Run 是对象实例的一种方法,它需要一些参数)。
无论如何,我的问题是,如何将其转换为非递归代码?
在我看来等效的非递归代码是:
void Parse(Foo foo)
{
//create a local stack variable to emulate recursion
Stack<Foo> foos = new Stack<Foo>();
foos.Add(foo());
start_subroutine:
A()
for (;;)
{
B();
if (C())
{
//instead of returning from a recursive call
if (foos.Count > 1)
{
foo = foos.Pop();
goto end_subroutine;
}
return;
}
if (D())
{
//instead of invoking Run as a subroutine, bring its functionality inline
//Run();
X();
if (Y())
{
//instead of calling self recursively
//Parse();
//push onto a local stack variable and jump
foos.Add(foo);
goto start_subroutine;
}
end_subroutine:
Z();
}
E();
}
}
我可以这样做,但是如果不使用 goto,我不知道该怎么做;而且我不记得曾经看到有人写过这是需要 goto 的情况之一。
最佳答案
我认为您走在正确的轨道上!在这种情况下,我没有看到使用 goto 有任何实际问题。代码中发生的事情真的非常清楚,人们试图避免直接跳转的唯一原因是它在阅读别人的代码时会导致混淆。
如果您将其结构保持得井井有条,并将大部分实现代码放在其他函数中,那么这看起来完全合理。特别是因为您只使用非递归代码进行分析:)
祝你好运,但你最终会继续前进!
关于c# - 避免递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1220000/