如何获得列表的反向对?

问题描述 投票:2回答:2

如何在Prolog中反转一些列表?

例如:

?- reversePairs([1,2,3,4,5,6,7,9], R).
R = [2,1,4,3,6,5,9,7].                     % expected answer

到目前为止,我编写了以下代码:

reversePairs([X,Y|Xs], ReversedList) :-
   reversePairs([X,Y|Xs], [], ReversedList).

reversePairs([], ReversedList, ReversedList).
reversePairs([X,Y|Xs], Accum, ReversedList) :-
   reversePairs(Xs, [X,Y|Accum], ReversedList).

我的代码给了我以下答案:

?- reversePairs([1,2,3,4,5,6,7,9], R).
R = [7,9,5,6,3,4,1,2].                     % observed answer

如何更正我的代码以获得我想要的答案?有什么建议吗?

list prolog reverse
2个回答
4
投票

简单地说

reversePairs([],[]).

reversePairs([X,Y|T], [Y,X|RT]) :-
    reversePairs(T, RT).

如果元素的数量是奇数,则此代码将失败。你想为这个案子做些什么?


4
投票

这是DCGs的一个有趣的可能性:

reverp, [B,A] --> [A,B], !, reverp.
reverp --> [].

reversePairs(L1,L2) :- phrase(reverp,L1,L2).

它也适用于具有奇数个元素的列表。

示例查询:

?- reversePairs([1,2,3,4,5,6,7,9], R).
R = [2, 1, 4, 3, 6, 5, 9, 7].

?- reversePairs([1,2,3,4,5,6,7,8,9], R).
R = [2, 1, 4, 3, 6, 5, 8, 7, 9].

可以很容易地推广到N个元素:

revern(N), Lr --> { length(L,N) }, L, !, { reverse(L,Lr) }, revern(N).
revern(_) --> [].

reverseNuples(N,L1,L2) :- phrase(revern(N),L1,L2).

示例查询:

?- reverseNuples(3,[1,2,3,4,5,6,7,9],R).
R = [3, 2, 1, 6, 5, 4, 7, 9].

正如@repeat在下面的评论中提到的那样,reversePairs不是对称的:查询

?- reversePairs(L,[2,1,4,3,6,5]).

将永远循环。要解决这个问题,我们可以使用same_length/2来确保两个术语都是相同长度的列表:

reversePairs(L1,L2) :-
    same_length(L1,L2),
    phrase(reverp,L1,L2).
© www.soinside.com 2019 - 2024. All rights reserved.