我用递归编写了河内塔问题的代码,并在在线lua编译器上运行它。如果我将输入放到14之上,它将无法运行。
local num = io.read("*n")
local count = 0
function hanoi(n, st, mid, dst)
if n == 1 then
count = count + 1
print(st, dst)
else
hanoi(n-1, st, dst, mid)
count = count + 1
print(st, dst)
hanoi(n-1, mid, st, dst)
end
end
hanoi(num, 1, 2, 3)
print(count)
我认为可以通过适当的尾调用来解决,但是据我所知,正确的尾调用必须返回相同的函数。但是在该代码中,有两个递归的“ hanoi”函数。
这在lua中是正确的尾声吗?
function f(args)
return f(args_1), f(args_2)
end
有什么方法可以正确地处理河内问题吗?
答案 0 :(得分:2)
正确的尾调用与调用同一函数无关。如果该函数在必要条件下发生,则对任何函数的调用都将是尾部调用,并且不限于递归。
在您的示例中:
function hanoi(n, st, mid, dst)
if n == 1 then
count = count + 1
print(st, dst)
else
hanoi(n-1, st, dst, mid) -- you continue after this call,
-- possibly expecting the result, this call
-- can't be a proper tail call
count = count + 1
print(st, dst)
hanoi(n-1, mid, st, dst) -- this call can be made a tail call,
-- just return the result of that call
return hanoi(n-1, mid, st, dst) -- now this is a proper tail call
end
end
该函数必须返回调用结果,不得使用或更改调用结果。
在您的河内示例中,只能将第二个电话设为尾部呼叫,而不能将其作为第一个电话。