【发布时间】:2014-01-17 15:10:45
【问题描述】:
众所周知,所有递归函数都可以只使用一个循环和一个堆栈来编写。虽然这种转换可以被批评为丑陋或可读性差,但它的主要用途显然是避免破坏堆。
有很自然的方法可以将简单的递归函数转换为循环。例如,使用累加器进行简单的尾递归消除。到目前为止,我还没有看到这个问题的明确答案。
至少对我来说,有时将这样的递归函数转换为循环似乎是黑魔法,提供了一个堆栈。例如,考虑为
编写一个非递归版本f(n) = n, if n <= 1
f(n) = f(n-1) + f(n-2) + 1, if n > 1
这个问题的核心是:
- 是否有一种清晰的通用方法可以将递归函数转换为循环+堆栈?
【问题讨论】:
-
如果你的例子被实现,它不会终止。
-
哦,对不起。这就是斐波那契 + 1 函数。我的意思是 f(n-1) 而不是 f(n+1),我编辑了。谢谢你的建议!
-
话虽如此,我不确定是否有通用策略,因为它在很大程度上取决于两件事:递归(通过参数)传递哪些信息以及从递归返回哪些信息(通过返回值)。它还取决于有多少递归调用。因此,可能存在转换算法,但它并非易事。
-
"...所有递归函数都可以编写...单循环和堆栈"可能有点夸大其词,但我不确定。我想像
int f(int x, int y) { return f(x/2, y) * f(f(y-3, x)-f(y, x)) / f(y, x*f(x-1, y)/f(x-f(x-1, y), y-1)); }这样的东西可能会被重写为一个循环,但我不想这样做......然后是相互递归的情况,比如f()调用g()调用f(),等等开,即使有更大的周期... -
是的,我确信它确实存在。编译器所做的就是一个例子。我想通过精确模拟编译器的工作来解决这个问题的一种方法,但我认为有一种更简单的方法。