好吧,在过去的几个小时里,我一直试图将给定列表的第二项与倒数第二项交换(倒数第二项)。列出[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
是包含交换元素的新列表。答案 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),也许这个解决方案更直观。