明天的明天 永远的永远 未知的一切 我与你一起承担 ??

是非成败转头空 青山依旧在 几度夕阳红 。。。
随笔 - 1277, 文章 - 0, 评论 - 214, 阅读 - 321万
  博客园  :: 首页  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

.Net 生成不重复的随机数

Posted on   且行且思  阅读(9215)  评论(1编辑  收藏  举报
复制代码
int myran = 10;//初始化myran 
public static int GenForInt(int minvalue, int maxvalue,ref int myran)  //自动生成int型的随机数据 

    Random ran 
= new Random();
    
int RandKey; 
    
do 
    { 
         RandKey 
= ran.Next(minvalue, maxvalue); 
    }
while (RandKey == myran); 
    Console.WriteLine(
"RandKey:" + RandKey); 
    myran 
= RandKey; //将本次的随机值赋给myran 
    return RandKey; 
}
复制代码




先来说说随机数算法的实现.借用C数值算法里的一句话:利用计算机,这种人类所设计的
各种机器中最精确,最能做出确切判断的机器,来产生"随机数",这看上去有些自相矛盾.甚至在
概念上是讲不通的.任何程序必将产生完全可以预计的结果.因而不是真正的"随机数".

现在各种语言中的随机数产生函数所产生的"随机数",实际上被称之为"伪随机数".可以将
整个随机数函数看做这样一个表达式:

A = R(s)

其中R是随机函数,s是种子.A是一个数列.即对于任意一个种子s,经过R的计算后,总有一个确定
的数列A与之对应.而当在C#里调用var rnd = new Random (s)或在C里调用srand(s)实质上
所做工作之一就是设定这个种子.而rnd.Next();或rand()只不过是在A上取下一个元素而已.当然实
际的实现不可能事先计算一个数列A,所以rand()相当于由s计算出下一个数字s',然后将s'作为新
的种子赋值给s,最后将s'作为结果返回.


**-------------------------
接下来就是两种常见的错误用法了:

for (int i=0;i<n;++i)
{
    var rnd 
= new Random (s);//s是实先确定的一个数字
    Console.Write ("{0},",rnd.Next());
}


这样使用随机数产生器只会产生一个固定的常数N.
因为每次都用同一个种子初始化了随机数产生器后调用了Next().
所取得的都是数列A上的第一个元素.而这个元素的值肯定是固定
的(当然N取什么值要看随机函数的实现而定).

而第二种情况就更常见了:

for (int i=0;i<n;++i)
{
    var rnd 
= new Random ();//用系统时间作为种子
    Console.Write ("{0},",rnd.Next());
}

这样调用应该是希望通过时间的不同来达到随机的效果;但是得到的结果就和我那位朋友一样.会是形似
97,97,97,97,....97,30,30,30,30,30,30,30,30,30,30,30,30,....,27,27,27,27,27,27,....
的一串数列.这是因为Windows系统时钟的更新频率大概在10ms左右.而这个for循环的执行显然要快
得多.于是在一段执行时间内Environment.TickCount (Random的默认种子)或是C的time函数返回的
都是同一个值.从而导致rnd.Next在一段时间内返回一个常数.


ps:在一个经常用到随机数的程序中,可初始化一个全局的随机数产生器,在
之后要用到随机数的地方就直接调用Next,而不用每次都构造一个Random.
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示