Prolog - 转换为尾递归
Prolog - transforming to tail recursion
作为Prolog的新手,我了解到尾递归是优化的。因此,我正在尝试将以下程序转换为尾递归程序。
sum([], 0).
sum([H|T], N):-
sum(T, X),
N is X + H.
这是我试过的方法,很明显我在逻辑上漏掉了一些东西:
sum(List,Sum):-
sum1(List,0,Sum).
sum1([Element|List],Accumulator,Sum):-
(NewAccumulator is Accumulator + Element,
sum1(List,NewAccumulator,Sum);
List=[] -> Sum = Accumulator
).
我程序中的问题是将列表中除最后一个数字之外的所有数字相加。我怎样才能改进这个程序?谢谢
问题是你程序写错了。这是正确的:
sum(List, Sum) :-
sum_1(List, 0, Sum).
sum_1([], Sum, Sum).
sum_1([H|T], Sum0, Sum) :-
Sum1 is Sum0 + H,
sum_1(T, Sum1, Sum).
但你可以在 Whosebug 上用谷歌搜索这个的一些版本。
这也是一个简单的折叠列表:
sum([H|T], Sum) :-
foldl(add, T, H, Sum).
add(X, Y, Z) :- Z is X + Y.
我同意TA_intern的解决方案,但这里有一个补充来告诉你为什么你的程序出错了。
以下程序尽可能多地保留了您的代码,但它是正确的:
sum(List,Sum):-
sum1(List,0,Sum).
sum1([Element|List],Accumulator,Sum):-
NewAccumulator is Accumulator + Element,
(sum1(List,NewAccumulator,Sum);
List=[] -> Sum = NewAccumulator
).
你有 List=[] -> Sum = Accumulator
,这意味着如果你的列表尾部为空,你取 Accumulator
,这是 Element
之前所有元素的总和。
保留更多代码的替代方法是:
sum1([Element|List], Accumulator, Sum) :-
( NewAccumulator is Accumulator+Element,
sum1(List, NewAccumulator, Sum)
; List=[]
-> Sum is Accumulator+Element
).
不过,我个人更喜欢TA_intern的解决方案。
作为Prolog的新手,我了解到尾递归是优化的。因此,我正在尝试将以下程序转换为尾递归程序。
sum([], 0).
sum([H|T], N):-
sum(T, X),
N is X + H.
这是我试过的方法,很明显我在逻辑上漏掉了一些东西:
sum(List,Sum):-
sum1(List,0,Sum).
sum1([Element|List],Accumulator,Sum):-
(NewAccumulator is Accumulator + Element,
sum1(List,NewAccumulator,Sum);
List=[] -> Sum = Accumulator
).
我程序中的问题是将列表中除最后一个数字之外的所有数字相加。我怎样才能改进这个程序?谢谢
问题是你程序写错了。这是正确的:
sum(List, Sum) :-
sum_1(List, 0, Sum).
sum_1([], Sum, Sum).
sum_1([H|T], Sum0, Sum) :-
Sum1 is Sum0 + H,
sum_1(T, Sum1, Sum).
但你可以在 Whosebug 上用谷歌搜索这个的一些版本。
这也是一个简单的折叠列表:
sum([H|T], Sum) :-
foldl(add, T, H, Sum).
add(X, Y, Z) :- Z is X + Y.
我同意TA_intern的解决方案,但这里有一个补充来告诉你为什么你的程序出错了。
以下程序尽可能多地保留了您的代码,但它是正确的:
sum(List,Sum):-
sum1(List,0,Sum).
sum1([Element|List],Accumulator,Sum):-
NewAccumulator is Accumulator + Element,
(sum1(List,NewAccumulator,Sum);
List=[] -> Sum = NewAccumulator
).
你有 List=[] -> Sum = Accumulator
,这意味着如果你的列表尾部为空,你取 Accumulator
,这是 Element
之前所有元素的总和。
保留更多代码的替代方法是:
sum1([Element|List], Accumulator, Sum) :-
( NewAccumulator is Accumulator+Element,
sum1(List, NewAccumulator, Sum)
; List=[]
-> Sum is Accumulator+Element
).
不过,我个人更喜欢TA_intern的解决方案。