从列表序言中交换第二个和prelast元素

时间:2013-09-03 17:21:39

标签: prolog swap elements

好吧,在过去的几个小时里,我一直试图将给定列表的第二项与倒数第二项交换(倒数第二项)。列出[a,b,c,d,e,f]列表,我想获得[a,e,c,d,b,f]。例如:

correct(List1,X,List2)
?-correct([a,y,b,c,d,e,x,f],x,List2).
List2[a,x,b,c,d,e,y,f].
  • List1是我要交换第二个和倒数第二个(倒数第二个)元素的列表。
  • X是倒数第二个元素。
  • List2是包含交换元素的新列表。

3 个答案:

答案 0 :(得分:2)

mbratch和CapelliC发布的解决方案均未能通过以下基本案例:

?- correct([a,y], X, List2).
false.

以下解决方案负责此基本情况,并且不依赖于可能可用或不可用的列表谓词。它遍历列表一次,并且比其他两个解决方案更有效:

correct([PreLast, Second], Second, [Second, PreLast]) :-
    !.
correct([First, Second, Last], Second, [First, Second, Last]) :-
    !.
correct([First, Second| InRest], PreLast, [First, PreLast| OutRest]) :-
    correct_aux(InRest, Second, PreLast, OutRest).

correct_aux([PreLast, Last], Second, PreLast, [Second, Last]) :-
    !.
correct_aux([Other| InRest], Second, PreLast, [Other| OutRest]) :-
    correct_aux(InRest, Second, PreLast, OutRest).

示例查询:

?- correct([a,b], X, List).
X = b,
List = [b, a].

?- correct([a,b,c], X, List).
X = b,
List = [a, b, c].

?- correct([a,b,c,d], X, List).
X = c,
List = [a, c, b, d].

?- correct([a,b,c,d,e], X, List).
X = d,
List = [a, d, c, b, e].

答案 1 :(得分:1)

这适用于长度为4或更长的列表:

correct( [H1|[H2|T1]], X, [H1|[X|T2]] ) :-
   reverse(T1, [HR|[X|TR]]),
   reverse([HR|[H2|TR]], T2).

| ?- correct( [1,2,3,4,5,6], X, L ).

L = [1,5,3,4,2,6]
X = 5

(1 ms) yes
| ?-

您可以通过添加两个谓词来包含较短的案例(如果这是意图),将解决方案带到:

correct( [A,X], X, [X,A] ).
correct( [A,X,B], X, [A,X,B] ).
correct( [H1|[H2|T1]], X, [H1|[X|T2]] ) :-
   reverse(T1, [HR|[X|TR]]),
   reverse([HR|[H2|TR]], T2).

答案 2 :(得分:1)

另一个可用的内置是追加/ 2:

3 ?- [user].
correct(L, X, R) :- append([[A,B],C,[X,E]], L), append([[A,X],C,[B,E]], R).
|: 
% user://2 compiled 0.02 sec, 2 clauses
true.

4 ?- correct( [1,2,3,4,5,6], X, L ).
X = 5,
L = [1, 5, 3, 4, 2, 6] ;

我喜欢mbratch one(+1),也许这个解决方案更直观。