2015-09-04 77 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)) $