我试图编写代码以反转Prolog中的列表。
我的工作成果是:
reverse(X,X).
reverse([X|Y],[H|X]):-
reverse(Y,H).
我在prolog上运行了这段代码,但它不起作用。 事实似乎对我来说是正确的,我无法找到错误。 你能救我吗?
答案 0 :(得分:2)
我的方法使用一个空的累加器列表(如注释中的joel76所述),它以一个接一个的相反顺序填充列表元素。
% reverse/2
% reverse(List,Result)
%
% Result will be the reversed list that gets returned
reverse(List,Result) :-
% call the accumulator method with the list and an empty placeholder list
reverse(List,[],Result).
% reverse/3
% reverse(List,Accumulator,ReverseList)
%
% >> stop rule for recursion
% -- checks whether initial List is empty (aka the reversing process is done)
% -- returns the ReversedList if completed, otherwise carry ReverseList over throughout the next iteration
reverse([],ReversedList,ReversedList).
% actual reversing method
reverse([Head|Tail],RestTail,ReverseList) :-
reverse(Tail,[Head|RestTail],ReverseList).
在SWI中执行这些语句时,例如reverse([a,b,c,d],X).
,其背后的想法变得更加清晰:
?- reverse([a,b,c,d],X).
Call: (7) reverse([a,b,c,d], _G2273) ?
Call: (8) reverse([a,b,c,d],[], _G2273) ?
Call: (9) reverse( [b,c,d],[a], _G2273) ?
Call: (10) reverse( [c,d],[b,a], _G2273) ?
Call: (11) reverse( [d],[c,b,a], _G2273) ?
Call: (12) reverse( [],[d,c,b,a],_G2273) ?
Exit: (12) reverse( [],[d,c,b,a],[d,c,b,a]) ?
Exit: (11) reverse( [d],[c,b,a], [d,c,b,a]) ?
Exit: (10) reverse( [c,d],[b,a], [d,c,b,a]) ?
Exit: (9) reverse( [b,c,d],[a], [d,c,b,a]) ?
Exit: (8) reverse([a,b,c,d],[], [d,c,b,a]) ?
Exit: (7) reverse([a,b,c,d], [d,c,b,a]) ?
X = [d,c,b,a].
说明:想象一下,初始列表是一堆元素。通过像[Head|Tail]
这样的列表拆分,每个初始列表的元素都会自行删除。通过创建新列表Head
,[Head|ReverseTail]
将添加到累加器列表中。 RevserseTail
只是累加器列表的当前内容,因此当前反向列表获得在第一个位置添加的初始列表Head
,而尾部跟在之后。以下步骤将递归调用reverse / 3,其中Tail
部分作为初始列表的剩余部分,[Head|ReverseTail]
作为当前反向列表,ReverseList
没有其他目的其他目的而不是作为过程结束时返回的值。
这将重复进行,直到初始列表的所有元素逐个添加到累加器并且初始列表为空,即递归停止并返回反向列表。