我产生了以下代码。
list_reverse([],[]).
list_reverse([X],[X]).
list_reverse(Ls,[R|Rs]) :-
last_elem(Ls,R),
without_last_elem(Ls,Next),
list_reverse(Next,Rs).
last_elem([E],E).
last_elem([_|Xs],E) :-
last_elem(Xs,E).
without_last_elem([X,_|[]],[X|[]]).
without_last_elem([X|T0],[X|T1]) :-
without_last_elem(T0,T1).
滑动:
?- list_reverse([1,2,3],X).
X = [3, 2, 1] ;
false.
这正是我想要的。
但是,如果我朝相反的方向前进,我会获得成功,然后才能终止。
?- list_reverse(X,[1,2,3]).
X = [3, 2, 1] ;
C-c C-cAction (h for help) ? a
abort
% Execution Aborted
我一直在努力理解的原因是为什么我首先要为X获得正确的解决方案。我的程序是否正确?
我不担心倒排清单,也不必担心获得正确解决方案然后终止的模式。这是我已经遇到过几次的模式。
该last_elem/2
可以保持较大的建设名单,这都应该被拒绝。但是您因此陷入了无限循环。
我们可以创建一个与累加器一起使用的函数,并同时对两个列表进行迭代。这意味着一旦左列表或右列表用尽,将不再进行递归调用:
reverse(L1, L2) :-
reverse(L1, [], L2, L2).
reverse([], L, L, []).
reverse([H|T], L1, R, [_|T2]) :-
reverse(T, [H|L1], R, T2).
因此,[H|T]
和[_|T2]
模式都会弹出列表的第一项,并且只有两个列表都用完时我们才匹配。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句