咨询区
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 arrayfor (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 orderfor (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(),这题目相信能给大家提供好的思路。