2012-12-22 28 views
12

我該如何隨機化StringList中的字符串,類似於這個在線工具的工作原理。如果任何人都熟悉它,看看這個:http://textmechanic.co/Randomize-List.htmlRandomize StringList

+0

http://en.m.wikipedia.org/wiki/Fisher-Yates_shuffle –

+0

@DavidHeffernan說真的這是什麼都與這個問題做? –

+2

@DavidHeffernan固定鏈接是: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – TridenT

回答

20

執行洗牌的一種常用算法是Fisher-Yates洗牌。這產生均勻分佈的排列。

要實現一個Delphi TStrings對象,你可以用這個上:現在

procedure Shuffle(Strings: TStrings); 
var 
    i: Integer; 
begin 
    for i := Strings.Count-1 downto 1 do 
    Strings.Exchange(i, Random(i+1)); 
end; 

,而在理論上,這將產生均勻分佈排列,實際性能在很大程度上取決於隨機數發生器的質量。這在計算機程序設計,第2卷,第3.4.2節算法P的Knuth的藝術討論

延伸閱讀:

+0

我們不能使用RandomRange嗎? –

+1

是的,桑托斯,但爲什麼要麻煩?隨機(i + 1)相當於RandomRange(0,i)。 –

+5

這是@Rob誰迴應?我不明白你爲什麼對那些儘可能地嘗試做事的人採取諷刺性的口吻,並且一路幫助你。 –

-3

要隨機化TStrings,創建一個TComparer與比較器隨機結果值,和排序TStrings它。

/// The Comparer 
TMyShuffleComparer= class(TComparer<string>) 
public 
    function Compare(const Left, Right: string): Integer; override; 
end; 

/// The randomizer 
function TMyShuffleComparer.Compare(const Left, Right: TCard): Integer; 
begin 
    // To sort, get a random number for compare result 
    Result := Random(100) - 50; 
end; 

/// How to call the comparer 
procedure TMyStrings.Shuffle; 
begin 
Sort(TMyShuffleComparer.Create); 
end; 

,或者直接撥打:

​​
+0

不可以。你的排序比較器不能是隨機的! –

+0

壞主意!不要這樣做。 – GolezTrol

+3

-1一個排序比較函數需要定義一個總的順序。這不是。這是一個簡單可怕的想法。我建議你刪除答案。閱讀一下,例如:http://blogs.msdn.com/b/oldnewthing/archive/2003/10/23/55408。aspx –

4

通過的StringList只是循環併爲每個項目不同的隨機地點:

for i := StringList.Count - 1 downto 1 do 
    StringList.Exchange(i, Random(i+1)); 

[編輯] 改變了循環有點使洗牌制服。

+0

是的,一個真正的洗牌:)最理智的一個。 –

+2

這個答案演示了維基百科中討論的Fisher-Yates錯誤之一,在[「實現錯誤」](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Implementation_errors)部分。雖然它仍然會產生混洗結果,這是所有問題的要求,它不是一個統一的洗牌算法。 RNG的質量與該問題是正交的。 –

+0

@RobKennedy好的。很高興知道,並且您指出的解釋說得很清楚。我已經改變了一點循環。使用downto,因爲它使循環更簡單。 '+ 1'是爲了防止Sattolo算法的意外實現。 – GolezTrol