Prolog,如何将项目从一个列表添加到第二个

时间:2018-01-07 16:29:59

标签: list prolog

早上好 我有以下格式的列表:

[(1-4),(2-4), (3-4)] 

我想将其更改为:

[4,3,4,2,4,1]

我尝试了2个程序:

changeList([], Z) :- 
    write(Z).
changeList([(A-B)|T], Z) :-
    append([A], Z, Y),
    append([B], Y, X),
    changeList(T, X).

和第二个:

changeList([],Z) :-
    write(Z).
changeList([(X-Y)|T], Z) :-
    W = [X|Z],
    C = [Y|W],
    changeList(T,C).

可悲的是,结果总是:[4,3,4,2,4,1 | _38]。我在哪里犯了错误?

2 个答案:

答案 0 :(得分:1)

您可以使用不同的方法来解决您的问题。如果要以相反的顺序获取列表,则需要另一个输入变量,即空列表。使用您的代码,您可以写:

changeList([],Z,Z).
changeList([(A-B)|T],Acc,Z) :-
    append([A], Acc, Y),
    append([B], Y, X),
    changeList(T,X,Z).

?- changeList([(1-4),(2-4),(3-4)],[],Z).
Z = [4, 3, 4, 2, 4, 1]

您可以避免以这种方式使用append/3

myReverse([],Z,Z).
myReverse([(A-B)|T],Acc,Z):- 
    myReverse(T,[B,A|Acc],Z).

?- myReverse([(1-4),(2-4),(3-4)],[],Z).
Z = [4, 3, 4, 2, 4, 1]

你有另一个解决方案是以有序方式打印列表,然后使用内置谓词(在SWI中)reverse/2来反转它:

changeListOrd([],[]).
changeListOrd([(A-B)|T], [A,B|TL]):-
    changeListOrd(T,TL).
change(L,Lout):-
    changeListOrd(L,L1),
    reverse(L1,Lout).

?- change([(1-4),(2-4),(3-4)],Z).
Z = [4, 3, 4, 2, 4, 1]

我建议您使用第二个解决方案(myReverse/3),这样您就不需要append/3reverse/2

答案 1 :(得分:0)

foldl / 4 是您的朋友:

changeList(In, Out) :-
    foldl(reverse_one, In, [], Out).

reverse_one((X-Y), In, [Y,X|In]).

示例:

?- changeList([(1-4),(2-4),(3-4)],Out).
Out = [4, 3, 4, 2, 4, 1].