2015-09-04 79 views
1

滚动列表最简单的方法是什么?Maxima:如何滚动(或移动)列表

考虑以下列表:

myList : [0,1,4,6,3] 

我要寻找一个roll()功能,将做到:

(%i0) roll(myList,1) 
(%o0) [3,0,1,4,6] 


(%i1) roll(myList,-1) 
(%o1) [1,4,6,3,0] 

我可以通过调用达到同样的效果:

myItem : pop(myList) 
myList : append(myList,myItem) 

问题是这只能在一个方向上工作(没有pop_back()函数据我所知(?)),这是一个双线程。有没有更好的方法来做到这一点

回答

2

那么,没有一个内置的功能。但我认为你可以使用rest来获得你想要的效果。

(%i10) rotate (e, n) := 
    if atom(e) then e 
    else block ([a : args(e)], 
      apply (op(e), 
       append (rest (a, length(a) - n), rest (a, -n)))) $ 
(%i11) foo : [a, b, c, d, e, f, g]; 
(%o11)      [a, b, c, d, e, f, g] 
(%i12) rotate (foo, 2); 
(%o12)      [f, g, a, b, c, d, e] 
(%i13) rotate (foo, 7); 
(%o13)      [a, b, c, d, e, f, g] 

这适用于所有表达式,而不仅仅是列表。

(%i16) rotate (f(1,2,3), 2); 
(%o16)       f(2, 3, 1) 

此实现不取负值nn比参数的数量越多,但我认为这将是很容易处理的。

我假设rotate将较小索引处的元素移动到更大的索引处。同样,如果你想让默认设置朝另一个方向发展,我认为做到这一点很容易。

编辑:实际上它没有必要分开出op(e)args(e)。如果e不是列表,则它可以打电话给rest(e, ...)。所以更简洁的版本是:

rotate (e, n) := 
    if atom(e) then e 
    else append (rest (e, length(e) - n), rest (e, -n)) $