我需要使用谓词交换列表中的两个元素和指定的索引:
swap(List, index1, index2).
我试过这种方式:
change_value([X|List], 0, Y, [Y|List2]) :-
copy_rest([X|List], List2).
change_value([], P, Y, []).
change_value([X|List], Pos, Y, [X|List2]) :-
X \== Y,
Pos > 0,
NewPos is Pos - 1,
change_value(List, NewPos, Y, List2).
copy_rest([], []).
copy_rest([X|List], [X|List2]) :-
copy_rest(List, List2).
有没有更好的解决方案?
非常感谢!
答案 0 :(得分:3)
无需编写递归代码!
只需使用内置谓词length/2
,same_length/2
和append/3
,就像这样:
list_i_j_swapped(As,I,J,Cs) :-
same_length(As,Cs),
append(BeforeI,[AtI|PastI],As),
append(BeforeI,[AtJ|PastI],Bs),
append(BeforeJ,[AtJ|PastJ],Bs),
append(BeforeJ,[AtI|PastJ],Cs),
length(BeforeI,I),
length(BeforeJ,J).
完成!让我们来使用吧!
?- list_i_j_swapped([e0,e1,e2,e3,e4,e5],5,1,Ys). Ys = [e0,e5,e2,e3,e4,e1] ; false.
OK!它也适用于“其他方向”吗?
?- list_i_j_swapped(Xs,5,1,[e0,e5,e2,e3,e4,e1]). Xs = [e0,e1,e2,e3,e4,e5] ; false.
好的!以下相当普遍的查询怎么样?
?- list_i_j_swapped([A,B,C],I,J,Ys).
I = 0, J = 0, Ys = [A,B,C]
; I = 0, J = 1, Ys = [B,A,C]
; I = 0, J = 2, Ys = [C,B,A]
; I = 1, J = 0, Ys = [B,A,C]
; I = 1, J = 1, Ys = [A,B,C]
; I = 1, J = 2, Ys = [A,C,B]
; I = 2, J = 0, Ys = [C,B,A]
; I = 2, J = 1, Ys = [A,C,B]
; I = J, J = 2, Ys = [A,B,C]
; false.
有效!最后,我们运行最常见的查询:
?- list_i_j_swapped(Xs,I,J,Ys).
I = 0, J = 0, Xs = [_A] , Ys = [_A]
; I = 0, J = 0, Xs = [_A,_B] , Ys = [_A,_B]
; I = 0, J = 1, Xs = [_A,_B] , Ys = [_B,_A]
; I = 1, J = 0, Xs = [_A,_B] , Ys = [_B,_A]
; I = 1, J = 1, Xs = [_A,_B] , Ys = [_A,_B]
; I = 0, J = 0, Xs = [_A,_B,_C], Ys = [_A,_B,_C]
...
开箱即用的公平计数?什么不喜欢?