0

嘿,我对序言递归和迭代有点困惑。我分别给出了递归和迭代中列表总和的代码,并想知道它们中的每一个是否正确......

add_r([],0).   
add_r([H|T],X) :- add_r(T,X1),X is H + X1.

add_i(List,Sum) :- add_i(List,0,Sum).   
add_i([H|T],I,Sum) :- I1 is I + H , add_i(T,I1,Sum).   
add_i([], I1, I1).

这里 add_r 是递归程序, add_i 是迭代的(根据我的说法)......我可能错了。这里的“I”用于迭代控制。
如果我错了,请纠正我。

4

2 回答 2

2

严格来说,Prolog不允许迭代,因为变量是“只写一次”(有点……)。

这两个谓词都是递归的,对我来说似乎是正确的。

它们之间的区别在于 add_i 是尾递归的(递归调用显示为最后一次),因此编译器可以对其进行优化(参见最后一次调用优化或Tail Call),将递归调用替换为 jump,从而避免线性堆栈add_r 所需的空间。

于 2013-09-25T05:46:09.517 回答
2

如果您使用 Abelson & Sussman(计算机程序的结构和解释)的术语,那么您是完全正确的。

在这种情况下,“迭代”意味着过程的状态仅由几个变量完全描述,“递归”意味着变量的数量随着每次调用而增长。此外,“递归”过程有两个阶段:增长和减少,当它增长时会留下“选择点”等(所有差异都在 SICP 中描述)。

在 Prolog 中,关于您的第二个示例,术语“尾递归”比“迭代”更常用。

于 2013-09-25T07:59:20.330 回答