得到一个随机数,只要它不在列表中

use*_*051 3 c# random

 var list = new List<int>(){1,17,18,21,30};
 Random rnd = new Random(DateTime.Now.Second);
 int r;
 do
 {
     r = rnd.Next(1, 30);
 }
 while (list.Contains(r));
Run Code Online (Sandbox Code Playgroud)

但我认为这是一个愚蠢的解决方案,任何人都可以给我一个更优化的方法吗?

如果有一种方法可以阻止Random实例返回已经返回的数字,那就更好了.

如果有人想知道我为什么需要这个,它是改组3字节数组并将它们组合成一个字节数组并生成3字节数组的第一步,它保存索引原始顺序,就像它在原始数组中一样.

Sco*_*ain 5

是的,使得它更高效的一件事是使用a HashSet<int>而不是List<int>查找HashSet比List快得多(但是构造函数的成本对于HashSet来说会稍微多一些).

此外,如果输入列表始终是相同的数字,则将其移出函数以帮助减少第一次生成HashSet的成本开销.


由于订单现在很重要,根据我的个人经验(请根据您自己的情况测试和配置文件),在列表中的大约14个项目之后,将列表转换为HashSet并执行查找比在列表本身中执行查找更快.

var list = new List<int>(){1,17,18,21,30};
Random rnd = new Random(DateTime.Now.Second);
int r;

//In this example with 5 items in the list the HashSet will be slower do to the cost 
// of creating it, but if we knew that the 5 items where fixed I would make this 
// outside of the function so I would only have to pay the cost once per program 
// start-up and it would be considered faster again due to amortized start-up cost.
var checkHashSet = new HashSet<int>(list); 

do
{
    r = rnd.Next(1, 30);
}
while (checkHashSet.Contains(rnd.Next(1, 30))); //Shouldent this be "r" not "rnd.Next(1,30)"?
Run Code Online (Sandbox Code Playgroud)

  • +1回答问题,但我相信OP需要[洗牌代码](http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp/1262619#1262619),而不是什么问题实际上是关于. (3认同)