2012-12-22 31 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