从列表中交换具有指定索引的两个元素 [英] Swap two elements from list with specified indices

查看:70
本文介绍了从列表中交换具有指定索引的两个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用谓词用指定的索引交换列表中的两个元素:

I need to swap two elements in list with specified indices using predicate:

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).

有没有更好的解决方案?

Is there any better solution?

非常感谢!

推荐答案

无需编写递归代码!

像这样简单地使用内置谓词length/2same_length/2append/3:

Simply use the builtin predicates length/2, same_length/2, and append/3 like so:

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).

完成!让我们使用它吧!

Done! Let's put it to use!


?- list_i_j_swapped([e0,e1,e2,e3,e4,e5],5,1,Ys).
  Ys = [e0,e5,e2,e3,e4,e1]
; false.

好!它也可以在其他方向"上工作吗?

OK! Does it work in the "other direction", too?


?- list_i_j_swapped(Xs,5,1,[e0,e5,e2,e3,e4,e1]).
  Xs = [e0,e1,e2,e3,e4,e5]
; false.

好的!接下来的一般查询呢?

Alright! What about the following quite general query?

?- 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.

成功了!最后,我们运行最通用的查询:

It worked! At last, we run the most general query:

?- 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]
...

开箱即用的公平枚举? 不喜欢什么?

Fair enumeration out-of-the-box? What's not to like?

这篇关于从列表中交换具有指定索引的两个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆