Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#创建随机唯一整数列表_C#_List_Unique_Distinct - Fatal编程技术网

C#创建随机唯一整数列表

C#创建随机唯一整数列表,c#,list,unique,distinct,C#,List,Unique,Distinct,我需要创建一个包含10亿个整数的列表,它们必须是唯一的。我也需要这是做得非常快 创建一个列表,一个接一个地添加随机数,然后检查每一个是否都是重复的速度非常慢 如果我只是用随机数填充一个列表,而不检查它们是否重复,然后使用distinct().toList()的话,速度似乎很快。我重复这一步,直到不再重复。但是,创建新列表所使用的额外内存不是最优的。是否有一种方法可以获得distinct()的性能,但它不创建新列表,而只是修改源列表?整数是否需要在某个范围内?如果是这样,您可以创建一个包含该范围内

我需要创建一个包含10亿个整数的列表,它们必须是唯一的。我也需要这是做得非常快

创建一个列表,一个接一个地添加随机数,然后检查每一个是否都是重复的速度非常慢


如果我只是用随机数填充一个列表,而不检查它们是否重复,然后使用distinct().toList()的话,速度似乎很快。我重复这一步,直到不再重复。但是,创建新列表所使用的额外内存不是最优的。是否有一种方法可以获得distinct()的性能,但它不创建新列表,而只是修改源列表?

整数是否需要在某个范围内?如果是这样,您可以创建一个包含该范围内所有数字(例如从1到100000000)的数组或列表,并将该列表洗牌

如果您从中提取的可能整数的数量明显大于您想要的整数的数量(比如因子2),您可以简单地使用
哈希集
检查重复项

List<int> GetUniqueRandoms(Random random, int count)
{
  List<int> result = new List<int>(count);
  HashSet<int> set = new HashSet<int>(count);
  for(int i = 0; i < count; i++)
  {
    int num;

    do
    {
      num = random.NextInt();
    while(!set.Add(num));

    result.Add(num);
  }
  return result;
}
但对于这两种解决方案,您需要足够的内存来存储
哈希集
列表



如果从中绘制的可能整数的数量与所需的整数数量大致相同,则可以创建一个包含所有整数的数组,对它们进行洗牌,最后删除不感兴趣的整数


您可以使用。

您可以在单独的
哈希集中跟踪重复项:

var set=newhashset();
var nums=新列表();
而(nums.Count<100000000){
int-num;
做{
num=rand.NextInt();
}而(!set.Contains(num));
set.Add(num);
列表。添加(num);
}

您需要一个单独的
列表来存储数字,因为哈希集不会保留您的随机顺序。

如果您以已排序但仍然是随机的方式创建列表(例如将随机数添加到列表的最后一个元素作为下一个元素),然后使用Fisher-Yates-Durstenfeld将列表洗牌,该怎么办?总的来说,这将在线性时间内执行,这与列表生成一样好。但是,它可能有一些显著的偏差,这会影响分布。

从字面上理解这个问题(一个包含10亿个整数的列表,它们必须是唯一的):

可枚举范围(0,100000000)
但是按照CodeCaster的回答,您可以创建列表并同时将其洗牌:

var count = 1000000000;
var list = new List<int>(count);
var random = new Random();
list.Add(0);
for (var i = 1; i < count; i++)
{
    var swap = random.Next(i - 1);
    list.Add(list[swap]);
    list[swap] = i;
}
var计数=100000000;
var列表=新列表(计数);
var random=新的random();
列表。添加(0);
对于(变量i=1;i
在保持随机性的同时,我发现这是最快的:

        Random rand = new Random();
        var ints = Enumerable.Range(0, numOfInts)
                                     .Select(i => new Tuple<int, int>(rand.Next(numOfInts), i))
                                     .OrderBy(i => i.Item1)
                                     .Select(i => i.Item2);
Random rand=new Random();
var ints=可枚举的范围(0,numOfInts)
.Select(i=>newtuple(rand.Next(numOfInts),i))
.OrderBy(i=>i.Item1)
.选择(i=>i.Item2);

…基本上是为每个整数分配一个随机id,然后按该id排序并选择结果整数列表。

要创建整数的范围有多大?这是C语言之前要求的。投票率最高的答案(与被接受的答案相反)有一些建议可以移植到C#。您将这些INT存储在什么数据类型中?一个32位整数无论如何只能容纳21亿(2147483647),所以你的“随机性”是有限制的。@Darin他们在.net 4中添加了这个功能吗?在.net 2中,2GB限制甚至适用于64位应用程序。你没有在问题中包含足够的信息来给出解决方案。例如,您是要求列表以随机顺序排列,还是仅要求列表包含随机整数?(“选择六张”式彩票选择六个随机的不同整数;顺序无关紧要。但当从列表中选择六首随机歌曲并播放它们时,顺序也应该是随机的。)整数的范围是什么?它们可能是负面的吗?它们是否可以比Int32中的尺寸更大?一个Int64?当列表中的内容越来越多时,它的速度会越来越慢。找到列表中最后一个数字可能需要几个小时。@CodeCaster:是的。如果洗牌是一个选项,那么它是一个更好的选项。让两个对象包含所有整数不是一个选项。内部循环将永远运行,因为集合最初为空,并且永远不包含num。应该从do循环条件中删除“!”。为什么?我没有说我想迭代哈希集。我只会用它来检查副本。
Enumerable<int>.Range(0, 1000000000)
var count = 1000000000;
var list = new List<int>(count);
var random = new Random();
list.Add(0);
for (var i = 1; i < count; i++)
{
    var swap = random.Next(i - 1);
    list.Add(list[swap]);
    list[swap] = i;
}
        Random rand = new Random();
        var ints = Enumerable.Range(0, numOfInts)
                                     .Select(i => new Tuple<int, int>(rand.Next(numOfInts), i))
                                     .OrderBy(i => i.Item1)
                                     .Select(i => i.Item2);