我有以下代码。试图制作一个反向清单。但它不起作用。
reverse([],[H|T]).
reverse([H|T],Z) :- reverse(T,[H|Z]).
我在prolog中运行它,我得到了这个:
1 ?- trace, reverse([1,2,3],X).
Call: (7) reverse([1, 2, 3], _G396) ? creep
Call: (8) reverse([2, 3], [1|_G396]) ? creep
Call: (9) reverse([3], [2, 1|_G396]) ? creep
Call: (10) reverse([], [3, 2, 1|_G396]) ? creep
Exit: (10) reverse([], [3, 2, 1|_G396]) ? creep
Exit: (9) reverse([3], [2, 1|_G396]) ? creep
Exit: (8) reverse([2, 3], [1|_G396]) ? creep
Exit: (7) reverse([1, 2, 3], _G396) ? creep
true.
这应该给我[3,2,1],而不是[1,2,3]。这里出了什么问题??
答案 0 :(得分:6)
当列表为空时,其反向为空。 所以
reverse([], []).
在另一种情况下,您将在列表其余部分的最后添加列表的第一个元素。所以:
reverse([H|T],Z) :-
reverse(T,Z1),
append(Z1, [H], Z).
答案 1 :(得分:3)
你几乎做对了。你需要的是一个“累加器”,它收集到目前为止的结果并在递归结束时将它传递给返回变量:
reverse([],Z,Z).
reverse([H|T],Z,Acc) :- reverse(T,Z,[H|Acc]).
否则反转列表会被遗忘,因为函数会从递归调用中返回。当您致电reverse/3
时,您需要使用空列表实例化累加器:
?- reverse([1,2,3],X,[]).
如果执行跟踪,您将看到第二个参数在原始列表为空之前未实例化。