早上好 我有以下格式的列表:
[(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]。我在哪里犯了错误?
答案 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/3
和reverse/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].