我应该表明两个算法以相同的顺序执行相同的语句。一个是另一个的尾递归版本。它们是用埃菲尔写的。
tail_rec(x:instance_type):result_type is
local
y:instance_type;
do
if b(x) then
Result :=c(x)
else
y:=d(x);
Result:=tail_rec(y)
end
end
然后是非尾递归版本。
non_rec(x:instance_type):result_type is
do
from until b(x) loop
x:= d(x)
end;
Result:= c(x)
end
其中b(x),c(x)和d(x)分别是BOOLEAN,result_type和instance_type类型的任何函数。
这两种算法如何相似?它们如何以相同的顺序执行相同的语句?
答案 0 :(得分:0)
用goto
替换所有控制流构造,(基本上将代码从Eiffel
转换为伪代码),并允许if
语句仅执行goto
可以证明,两个函数最终都由完全相同的指令集组成。
首先,为方便起见,请复制原始tail_rec
:
tail_rec(x:instance_type):result_type is
local
y:instance_type;
do
if b(x) then
Result := c(x)
else
y := d(x);
Result := tail_rec(y)
end
end
首先,为了方便起见,摆脱Eiffel的愚蠢Result :=
构造并将其替换为return
。 (否则,我们将不得不添加更多goto
s,坦率地说,越少越好。)
tail_rec(x:instance_type):result_type is
local
y:instance_type;
do
if b(x) then
return c(x)
end
y := d(x);
return tail_rec(y)
end
用if
- then
代替end
- if
- then goto
:
tail_rec(x:instance_type):result_type is
local
y:instance_type;
do
if not b(x) then goto label1
return c(x)
label1:
y := d(x);
return tail_rec(y)
end
将尾递归替换为另一个goto
:
tail_rec(x:instance_type):result_type is
do
label0:
if not b(x) then goto label1
return c(x)
label1:
x := d(x);
goto label0
end
将if not b(x)
替换为if b(x)
:
tail_rec(x:instance_type):result_type is
do
label0:
if b(x) then goto label1
x := d(x);
goto label0
label1:
return c(x)
end
与tail_rec
类似的转换应该将它变成完全相同的东西。