高质量的C代码.关于获取随机数

http://blog.csdn.net/kome2000/article/details/6585058

在C语言中使用rand()函数来获取随机数,但是如下语句

[cpp]  view plain copy
  1. int i;  
  2. i=rand();  


每次得到的随机数都是一样的,据了解在C/C++中这样做是为了方便调试。

如果要每次都产生不同的随机数,我们则需要增加
srand(time(NULL));这条语句,他的作用是以时间为种子,产生随机数(我们都知道时间是在不断变化的,但两次获取随机数要在1毫秒后,否则数值还是一样)。

本文主要讨论的是如何在较短时间内获取不同的随机数


1.1 通过交换使得原有顺序打乱,得到随机效果。
我们在做棋盘,麻将之类的游戏的时候,需要初始化游戏,也就是洗牌,牌数固定54张,初始时的顺序也固定,比如黑桃A23456..K等,
也就是有一个数组card[54]

[cpp]  view plain copy
  1. int card[54];  
  2. int i;  
  3. //洗牌  
  4. for(i=0;i<54;i++)  
  5. {  
  6.     int tempIndex = rand(54);   //获取0到53的随机数  
  7.     int temp;                   //交换2张牌  
  8.     temp = card[i];  
  9.     card[i] = card[tempIndex];  
  10.     card[tempIndex] = card[i];  
  11. }  


这样就可以达到洗牌的目的了,但是rand()这个函数在较短时间内执行会得到很多相同的数,这并不是我们想要的,下面会有办法解决

1.2 类似扫雷游戏中,使用随机数布雷
要随机一个行坐标,一个列坐标,然后把这个坐标位置上置为雷。
一个行坐标,一个列坐标,这在较短时间内随机出来的数会一样,我们可以把行列放在一起,从2维降到1维,再布雷,
比如一个10*12的雷区(10列*12行)

[cpp]  view plain copy
  1. int i;  
  2. int area=10*12;  
  3. //布雷  
  4. for(i=0;i<area;i++)  
  5. {  
  6.     int tempIndex = rand(area); //获取0-119的随机数  
  7.     int row = tempIndex%12;     //行坐标  
  8.     int col = tempIndex/10;     //列坐标  
  9.     //map[col][row] = -1;       //将该位置设置成雷  
  10. }  


通过降低维数,在一个循环内使用一次获取随机数,同样会有2次获取的随机数一样的问题,

1.3 使用一个数组记录一组随机数,再次使用的时候,可以在很短时间内获取到不同的随机数
这组数据可以在用户每次按键操作的时候获取当时的系统时间,把这些数据作为种子,用一个索引来表示当前数据所在位置
或者可以使用循环链表,下面为方便起见使用的是数组!

[cpp]  view plain copy
  1. const int RAND_SIZE = 100;  
  2. static int32 rand[RAND_SIZE];  
  3. static int randIndex=0;  
  4. void setRandomValue(int32 value)  
  5. {  
  6.     randIndex++;  
  7.     randIndex = randIndex % RAND_SIZE;  
  8.     rand[randIndex] = value;  
  9. }  
  10. static int32 getRandomValue()  
  11. {  
  12.     randIndex--;  
  13.     if( randIndex<0 )  
  14.     {  
  15.         randIndex = RAND_SIZE-1;  
  16.     }  
  17.     return rand[randIndex];  
  18. }  
  19. static int32 lastRandSeed;  
  20. //这个方法可以在极短时间内获取不同的随机数  
  21. int32 random(int32 rand)  
  22. {  
  23.     if( rand<=0 || rand>=65535)  
  24.     {  
  25.         return 1;  
  26.     }  
  27.     return getRandomValue()%rand;  
  28. }  
  29. //获得一个在 [min,max]之间的随机数  
  30. int32 randomInterval( int32 min, int32 max )  
  31. {  
  32.     int32 interval = max - min;  
  33.     if( interval <= 0 )  
  34.     {  
  35.         return min;  
  36.     }  
  37.     else  
  38.     {  
  39.         return min + random( interval );  
  40.     }  
  41. }  


这个方法虽然好,但有个前提需要用户的操作,来获取随机数的内容,如果没有操作,或者是程序一开始就需要随机数呢?

1.4 我们可以自己做一个表来存储一些随机数,也就是说上例中的随机数数组实现由程序员给出,
比如我们可以做一个2维数组
rand[20][20]={61987,2187,...5741,9871,..};
等等
或者将这些数写到一个2进制文件中,
然后程序使用的时候只随机一个起点,或者一个读取规则(纵向,横向,斜向,回旋)等等,
这样就可以在很短时间内做出来很多个不规则的随机数啦!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值