回答
較短版本的費雪耶茨算法:
on shuffle(l)
set i to count of l
repeat while i ≥ 2
set j to random number from 1 to i
tell l to set {item i, item j} to {item j, item i}
set i to i - 1
end repeat
l
end shuffle
set l to {}
repeat 1000 times
set end of l to random number from 1 to 1000
end repeat
shuffle(l)
有我* ...... * 2 =我!可能的隨機數字序列。它們全部對應於我的一個排列!列表的排列。
一個使用腳本對象的更快版本:
on shuffle(input)
script s
property l : input
end script
set i to count of l of s
repeat while i ≥ 2
set j to random number from 1 to i
set {item i of l of s, item j of l of s} to {item j of l of s, item i of l of s}
set i to i - 1
end repeat
l of s
end shuffle
腳本歷時約:
- 0.15和0.06秒1000個元素
- 12和0.5秒10000個元件
- 對於100000個元素,976秒和4秒
所以第一個腳本具有指數時間複雜性。 regulus發佈的腳本稍微慢一些。
當我將第一個腳本保存爲scpt並將10000個元素添加到列表中時,我遇到了limit for the number of items that can be saved in a compiled script。
我想我已經破解了它。包裹在一個易於使用的功能。
set myList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set answer to listShuffle(myList)
on listShuffle(theList)
set listLength to count of theList
repeat while listLength > 1
set r to random number from 1 to listLength
set item1 to item listLength of theList
set item2 to item r of theList
set item listLength of theList to item2
set item r of theList to item1
set listLength to listLength - 1
end repeat
return theList
end listShuffle
這實際上是Fisher-Yates算法。 Sattolo的算法將具有從1到listLength-1的隨機數,並且它僅產生作爲週期的排列(它將僅將{1,2,3}改變爲{2,3,1}或{3,1,2} })。 – user495470 2013-03-24 17:56:36
這是另一種選擇。而不是「洗牌」列表中,我們只是隨機從列表中搶項目,並把它們插入到一個新的列表...
set myList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set randomizedList to randomizeList(myList)
on randomizeList(theList)
set listCount to count of theList
set newList to {}
repeat listCount times
set subListCount to count of theList
set r to random number from 1 to subListCount
set end of newList to item r of theList
-- remove the random item from theList
if subListCount is 1 then
exit repeat
else if r = 1 then --> first item
set theList to items 2 thru end of theList
else if r = subListCount then --> last item
set theList to items 1 thru -2 of theList
else
set theList to items 1 thru (r - 1) of theList & items (r + 1) thru -1 of theList
end if
end repeat
return newList
end randomizeList
編輯:如果你想加快的大名單上的行動你可以使用腳本對象。當名單很大時,你會經常看到很大的速度增益。所以,你可以寫你使用腳本對象這樣的代碼......
set myList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set answer to listShuffle(myList)
on listShuffle(theList)
script s
property l : missing value
end script
set s's l to theList
set listLength to count of s's l
repeat while listLength > 1
set r to random number from 1 to listLength
set item1 to item listLength of s's l
set item2 to item r of s's l
set item listLength of s's l to item2
set item r of s's l to item1
set listLength to listLength - 1
end repeat
return s's l
end listShuffle
我是新來的applescript,上面的方法比我自己的解決方案更有效嗎? – regnix 2013-03-17 18:18:21
我不知道更有效率,但我敢打賭,你所有的數字都不會移動。例如,你可以從1到10中得到10個隨機數。因爲它們是隨機的,你可能不會得到每一個數字(有些數字會重複),因此在你的代碼中並不是每個項目都會被調用。在我的代碼中,我從列表中刪除該項目,然後獲得另一個隨機項目,直到我獲得所有項目。因此我的代碼作用於每個列表項。所以你決定哪種方法最適合你的情況。我只是想告訴你一個選擇。他們都混合到一定程度。 – regulus6633 2013-03-17 22:11:56
感謝您的回覆。我只是想知道,因爲在每種語言中,我總是會在某個時候結束洗牌陣列/列表,並正在尋找一個很好的片段來爲applescript添加書籤。我的代碼是來自維基百科的Sattolo算法的直接副本,適用於我。 我很擔心效率,因爲我正在洗牌目前約3,000件商品的清單,並期望它在我目前項目的最終版本中有很多。 (你總是不得不洗牌幾次,因爲你知道計算機上的「隨機」數字是什麼)) – regnix 2013-03-18 01:28:30
如果在新列表中的項目不必是唯一的,那麼你可以用非常有效的
set selectedItemVar to some item of list someItemListVar
我只是拋出我的解決方案。我個人只使用非常短的名單(約200項),從中我需要提取各種長度的獨特隨機子列表。將該算法應用於整個列表(即傳入count of mainList
,maxCount
)將導致原始列表的混洗版本。這不是爲了速度而構建的,但對於算法不強的人可能更容易獲得。
on randomizedSublist(mainList, maxCount)
set sublist to {} as list
repeat with x from 1 to maxCount
set oneItem to some item of mainList
repeat until sublist does not contain oneItem
set oneItem to some item of mainList
end repeat
set end of sublist to oneItem
end repeat
return sublist
end randomizedSublist
- 1. Python的兩個列表名單洗牌
- 2. 更好的方式來洗牌兩個相關的列表
- 3. 最簡單的方法來搜索多個表的所有列?
- 4. 有沒有簡單的方法來交換,其中值列表
- 5. 這個簡單的洗牌算法是否會返回隨機洗牌的撲克牌?
- 6. 有沒有簡單的方法來結合Dart中的兩個列表?
- 7. 有沒有更簡單的方法來刪除列表中的前兩個值?
- 8. 有沒有簡單的方法來表示Python列表中的base64字母表?
- 9. 有沒有更簡單的方法來改變列表元素
- 10. 有沒有一個簡短的方法來建立Yocto的配方列表包?
- 11. 有沒有簡單的方法來覆蓋列表對象的方法__getitem__?
- 12. 一個更簡單的方法來驗證一個井字棋牌
- 13. 是否有一種簡單的方法來刪除列表項中的空白
- 14. 最簡單的方法來形成兩個列表的聯合
- 15. 洗牌列表中隨機的Java
- 16. 有沒有更簡單的方法來寫/代表這個mapStateProps?
- 17. AppleScript的:用一個列表來清除另一個列表
- 18. 最簡單的方法來「存儲」一個類沒有綁定它的功能?
- 19. 卡片和洗牌方法
- 20. Ruby定製洗牌方法
- 21. 有沒有一種簡單的方法來document.createElement多個元素?
- 22. 有沒有簡單的方法來找到一個數字
- 23. 寫一個方法在VB.NET中洗牌一套
- 24. 最快的方法來分組數據幀,洗牌單個向量在R
- 25. 簡單的Java卡片遊戲 - 麻煩洗牌(陣列)
- 26. 使用不顯示列表列表的牌洗牌的輸出
- 27. 是存在一個簡單的方法來從特定的表
- 28. 有沒有一種簡單的方法在Python中編寫它?
- 29. 更簡單的方法來添加多個列表項目?
- 30. SimpleAudioEngine洗牌播放列表
你能解釋倒數第二行嗎? – 2014-11-29 15:14:31
實際上,你能否詳細說明如何設置{s中的項目i,s中的項目j}到{s中的項目j,s中的項目i}作品? – 2014-11-29 15:16:06