我需要谈谈我的任务和解决方案:
定义一个语句来反转两个参数,一个列表和另一个第二个列表,其元素的顺序相反。我们不能使用反向内置。
Example:
> invierte( [a, [b, c], d, [e, f]], L)
L = [[e, f], d, [b, c], a]
我的建议:
invierte([],[]).
invierte([X],[X]).
invierte([H|T], Result) :-
invierte([T|H]), Result).
我怀疑是否需要在一般情况下将输入第一个列表分为:
invierte([H|T], Result) :-
invierte([T|H]), Result).
或
invierte([H,Y|T], Result) :-
invierte([Y,H|T]), Result).
感谢您的提示!
答案 0 :(得分:3)
您可以使用foldl和差异列表:
:-use_module(library(lambda)).
inverse(In, Out) :-
foldl(\X^Y^Z^append_dl([X|U]-U, Y, Z), In, V-V, Out-[]).
append_dl(A-B, B-C, A-C).
例如
?- inverse([1,2,3], X).
X = [3,2,1].
修改强> 在User9213的第二个版本之后我们可以写
:-use_module(library(lambda)).
inverse(In, Out) :-
foldl(\X^Y^Z^Z=[X|Y], In, [], Out).
答案 1 :(得分:3)
如果你想做更多花哨而不是太花哨,你可以像这样使用foldl:
list_rev_foldl([], []).
list_rev_foldl([X|Xs], R) :-
foldl(rev, Xs, [X], R).
rev(X, Ys, [X|Ys]).
答案 2 :(得分:3)
在描述列表时,DCG通常会产生易于阅读的代码。另外,让我们选择一个更具声明性的名称,它反映了谓词的关系性质,比如list_invlist / 2。然后你描述一个反转列表的样子:
list_invlist(L,I) :- % the inverse of the list L
phrase(invseq(L),I). % is described by invseq//1
invseq([]) --> % the inverse of the empty list
[]. % is the empty list
invseq([X|Xs]) --> % the inverse of the list [X|Xs] is
invseq(Xs), % the inverse of the list Xs
[X]. % followed by X
您帖子中的示例查询:
?- list_invlist([a,[b,c],d,[e,f]],I).
I = [[e,f],d,[b,c],a]
请注意,谓词也可以在其他方向上使用,就像它的关系名称所暗示的那样。但是,在产生第一个解决方案list_invlist / 2循环之后。
?- list_invlist(L,[[e,f],d,[b,c],a]).
L = [a,[b,c],d,[e,f]] ? ;
... % <- loop
这是由于invseq // 2的递归规则中的左递归。您可以通过在list_invlist / 2中添加约束来限制两个列表的长度(DCG规则保持不变)来解决这个问题:
list_invlist(L,I) :-
samelength(L,I),
phrase(invseq(L),I).
samelength([],[]).
samelength([X|Xs],[Y|Ys]) :-
samelength(Xs,Ys).
现在,谓词终止于第二个查询:
?- list_invlist(L,[[e,f],d,[b,c],a]).
L = [a,[b,c],d,[e,f]]
到目前为止,您尚未使用内置函数或库来解决该问题。
答案 3 :(得分:0)
从一个堆叠的顶部取出并放到一个新堆栈的顶部 - 它是相反的:
list_rev(L, R) :-
list_rev(L, [], R). % "[]" is the new stack
list_rev([], R, R). % When original stack is empty the new stack is done
list_rev([X|Xs], Ys, R) :- % "[X|Xs]" takes X from the top of Xs
list_rev(Xs, [X|Ys], R). % ... and puts it on the top of Ys
有
?- list_rev([a, [b, c], d, [e, f]], R).
R = [[e, f], d, [b, c], a].