咨询区
-
Christian Peut
我的项目中需要生成若干个并且唯一的随机数,我用的是 System.Random
,种子给的是 DateTime.Now.Ticks
,参考如下代码:.
private void NewNumber()
{
Random a = new Random(DateTime.Now.Ticks.GetHashCode());
MyNumber = a.Next(0, 10);
}
当我多次调用 NewNumber()
方法时,我发现会经常出现重复的值,一些朋友说是因为每次都 new 了一下 Random
所致,建议提取出来,代码如下:
public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
MyNumber = a.Next(0, 10);
}
虽然随机性达到了,但我发现还是会存在 重复
的情况,请问是否有更好的解决方法。
回答区
-
tsme86
如果你仅仅是需要在 0-9
之间做 随机唯一
的话,我建议你用 洗牌策略
来打乱数组元素即可,参考如下代码:
static void Main(string[] args)
{
var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();
// Shuffle the array
for (int i = 0; i < nums.Length; ++i)
{
int randomIndex = rnd.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
// Now your array is randomized and you can simply print them in order
for (int i = 0; i < nums.Length; ++i)
Console.WriteLine(nums[i]);
}
-
JOSEFtw
如果你的生成范围小,我建议你用 Guid.NewGuid()
来实现随机性,但范围大的话,我不建议使用,因为性能是真的很差,参考代码如下:
static void Main(string[] args)
{
var result = Enumerable.Range(0, 9).OrderBy(g => Guid.NewGuid()).ToArray();
for (int i = 0; i < result.Length; ++i)
Console.WriteLine(result[i]);
}
-
Vasily Novsky
我是借用 HashSet
来找到 N 个随机并唯一的数字,道理很简单,HashSet
本身就可以保证数字的唯一性,参考如下代码:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class RnDHash
{
static void Main()
{
HashSet<int> rndIndexes = new HashSet<int>();
Random rng = new Random();
int maxNumber;
Console.Write("Please input Max number: ");
maxNumber = int.Parse(Console.ReadLine());
int iter = 0;
while (rndIndexes.Count != maxNumber)
{
int index = rng.Next(maxNumber);
rndIndexes.Add(index);
iter++;
}
Console.WriteLine("Random numbers were found in {0} iterations: ", iter);
foreach (int num in rndIndexes)
{
Console.WriteLine(num);
}
Console.ReadKey();
}
}
}
点评区
从时间复杂度以及条件允许的情况下,我觉得 洗牌策略
是一个好方案,其次是 HashSet,最后是 Guid.NewGuid(),这题目相信能给大家提供好的思路。