Delphi 随机化字符串列表

Delphi 随机化字符串列表,delphi,delphi-xe2,Delphi,Delphi Xe2,如何使StringList中的字符串随机化?类似于此在线工具的工作方式。如果有人熟悉它,请选中此项:要将t字符串随机化,请使用随机结果值从t比较程序创建一个比较器,并使用它对t字符串进行排序 /// The Comparer TMyShuffleComparer= class(TComparer<string>) public function Compare(const Left, Right: string): Integer; override; end; /// The

如何使StringList中的字符串随机化?类似于此在线工具的工作方式。如果有人熟悉它,请选中此项:

要将
t字符串
随机化,请使用随机结果值
t比较程序
创建一个比较器,并使用它对
t字符串
进行排序

/// 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;

只需在stringlist中循环,并为每个项指定一个不同的随机位置:

for i := StringList.Count - 1 downto 1 do
  StringList.Exchange(i, Random(i+1));
[编辑]
对循环进行了一些修改,以使洗牌均匀。

执行洗牌的一种常见算法是洗牌。这将生成均匀分布的排列

要在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;
现在,虽然理论上这将产生均匀分布的排列,但实际性能在很大程度上取决于随机数生成器的质量。这在Knuth的《计算机编程艺术》第二卷第3.4.2节算法P中进行了讨论

进一步阅读:

  • (维基百科)
  • 杰夫·阿特伍德的两篇关于洗牌的博客文章:和
  • (伊莱·本德斯基)
  • ,Donald Knuth,第2卷,第3.4.2节
  • (维基百科)


–耶茨_shuffle@DavidHeffernan说真的,这跟问题有什么关系@DavidHeffernan固定链接是:@DavidHeffernan啊,我以为你要把我送到一个渔夫链接:)@DavidHeffernan欢迎你发布你的解决方案。没有人会阻止你:)是的,这是一次真正的洗牌:)也是最理智的一次。这个答案展示了维基百科中讨论的费舍尔·耶茨的一个错误,在这一节中。虽然它仍然产生一个洗牌结果,这是所有的问题要求,它不是一个统一的洗牌算法。RNG的质量和这个问题是正交的。很高兴知道,你的解释很清楚。我稍微改变了一下循环。一直使用,因为它使循环更简单。
+1
是为了防止Sattolo算法的意外实现。因此,我删除了我所有的评论,因为它们不再适用于您的回答。我发现了关于这个主题的一些更好的帖子:-1排序比较函数需要定义总顺序。这不是。这简直是个糟糕的主意。我建议你删除答案。例如,阅读以下内容:不一致的比较函数可能会导致非终止排序函数和缓冲区溢出。它们不是洗牌列表的方法。虽然可以使用排序算法洗牌,但这不是怎么做的。即使你做对了,你也有比Fisher Yates慢得多的复杂代码。我根据你的评论进行了测试,现在我明白了我在比较器上的错误。试图回答这个问题,我已经纠正了自己的错误;)这是一种新颖的想法,但是,正如@Rob所说的,您的比较函数必须是(忽略SQL风格),否则您最终得到的结果列表混乱不堪。我们不能使用RandomRange吗?是的,Santos,但为什么要麻烦呢?Random(i+1)相当于RandomRange(0,i)。是@Rob响应的?我不明白你为什么对那些尽力做好事情并帮助你解决问题的人采取讽刺的语气。@DavidHeffernan yea然而你提供的解决方案几乎与GolezTrol完全一样:)一点也不。戈莱兹的代码是扭曲的。选择的某些排列比其他排列具有更高的概率。我怀疑你不想那样。
procedure Shuffle(Strings: TStrings);
var
  i: Integer;
begin
  for i := Strings.Count-1 downto 1 do 
    Strings.Exchange(i, Random(i+1));
end;