List 在prolog中反转列表的项顺序

List 在prolog中反转列表的项顺序,list,prolog,reverse,List,Prolog,Reverse,谁能给我解释一下下面的代码: t(L, NL) :- t(L, [], NL). t([], L, L). t([H|T], A, NL) :- t(T, [H|A], NL). 我会以完全不同的方式实施它: s([], []). s([H|T], NL) :- s(T, NT), append(NT, [H], NL). 使用累加器,即第二个参数。实际上,初始设置为空列表: t(L, NL) :- t(L, [], NL). % &leftar

谁能给我解释一下下面的代码:

t(L, NL) :-
    t(L, [], NL).
t([], L, L). 
t([H|T], A, NL) :-
    t(T, [H|A], NL).
我会以完全不同的方式实施它:

s([], []). 
s([H|T], NL) :-
    s(T, NT),
    append(NT, [H], NL).

使用累加器,即第二个参数。实际上,初始设置为空列表:

t(L, NL) :-
    t(L, [], NL).  % ← empty list
如果我们有一个列表
[1,4,2,5]
,那么每次我们都会在累加器前面加上列表的头部,然后在尾部递归,所以它看起来像:

 list (L)  | accumulator (A)
-----------------------------
 [1,4,2,5] |              []
 [4,2,5]   |             [1]
 [2,5]     |           [4,1]
 [5]       |         [2,4,1]
 []        |       [5,2,4,1]
因此,当我们最终调用
t/3
谓词且
L
为空时,累加器包含相反的列表

这样做的好处是效率高:预结束需要O(1)个时间,就像与
[H | T]
的统一一样,这意味着我们需要O(n)个时间来反转

append/3
在第一个参数的长度上采用线性时间,因此通过在此处使用
append/3
,可以在O(n2)时间内获得相反的结果

t([H|T], A, NL) :-
    t(T, [H|A], NL).  % ← prepend H to the accumutor.
 list (L)  | accumulator (A)
-----------------------------
 [1,4,2,5] |              []
 [4,2,5]   |             [1]
 [2,5]     |           [4,1]
 [5]       |         [2,4,1]
 []        |       [5,2,4,1]