随机洗牌列表框项目C#

随机洗牌列表框项目C#,c#,winforms,random,listbox,shuffle,C#,Winforms,Random,Listbox,Shuffle,如何在列表框中随机洗牌当前项目 我有这个代码,但它速度很慢,效率很低- private void shuffleItemsToolStripMenuItem_Click(object sender, EventArgs e) { ListBox.ObjectCollection list = listBox1.Items; Random rng = new Random(); int n = list.Count; while ( n > 1 ) {

如何在列表框中随机洗牌当前项目

我有这个代码,但它速度很慢,效率很低-

private void shuffleItemsToolStripMenuItem_Click(object sender, EventArgs e)
{
   ListBox.ObjectCollection list = listBox1.Items;
   Random rng = new Random();
   int n = list.Count;
   while ( n > 1 )
   {
      n--;
      int k = rng.Next(n + 1);
      string value = (string)list[k];
      list[k] = list[n];
      list[n] = value;
   }
}
虽然这段代码在技术上是可行的,但它非常慢,并且没有给出太多的变化,通常会给出相同的几个洗牌

我在谷歌上搜索了一个小时,一直找不到解决办法。我的头发快用完了


谢谢。

试试Fisher-Yates shuffle:

我猜您使用的是
winforms
列表框有一对方法
BeginUpdate
EndUpdate
用于快速更新项目(无需重新绘制),更改项目时重新绘制是减慢一切的原因之一。还请注意,此处不需要任何强制转换,这可能会使代码速度稍慢,请尝试以下操作:

private void shuffleItemsToolStripMenuItem_Click(object sender, EventArgs e) {
   ListBox.ObjectCollection list = listBox1.Items;       
   Random rng = new Random();
   int n = list.Count;
   //begin updating
   listBox1.BeginUpdate();
   while ( n > 1 ) {
    n--;
    int k = rng.Next(n + 1);
    object value = list[k];
    list[k] = list[n];
    list[n] = value;
   }
   listBox1.EndUpdate();
   listBox1.Invalidate();
}

但是我同意,即使不使用上面的一些调整,您的代码也不应该运行得这么慢。

上有一些答案可以帮助您。一个是Fisher-Yates洗牌算法,我不知道如何将Fisher-Yates算法应用于列表框。在这方面我需要很多帮助。我使用了你发布的代码,没有问题,你正在洗牌的列表有多大,为什么你认为它没有太多变化?一个11+项的列表。将列表洗牌10次,得到相同顺序的2或3个列表。我需要随机唯一地洗牌它的代码,而且不需要2秒钟以上的时间。@Smith我无法想象这个算法需要几秒钟来排序一个11项列表。离这一点都不远。如果这是你的问题,它与洗牌根本没有关系。这一定是由于与实际洗牌无关的原因。至于获得不同的洗牌,可能是您在足够近的时间间隔内创建了
随机
实例,使它们获得相同的种子;如果没有,则必须有足够小的序列和足够多的迭代,以使碰撞的几率实际上相当高。注意,“生日悖论”在这方面起作用。