加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C语言产生随机数序列的方法

(2014-10-16 22:32:14)
标签:

it

分类: 程序设计
 

一、随机数序列的产生

在软件测试、游戏等应用场合,经常需要用到随机数序列。在C语言中,随机数可以用rand()函数来产生。每次调用rand()函数,总会返回一个随机整数值,范围在0~RAND_MAX之间。对于int类型,RAND_MAX的值为32767

程序中引用rand()函数时,必须在程序的开头使用#include 语句,把stdlib.h头文件包含在内。

#include

#include

void main( void )

{

        int i;

     for( i=0; i<10; i++ )

          printf(" %d", rand());

        printf("\n");

}

程序运行以后,在屏幕上将显示出10个看上去没有明显规律性的整数。当这个序列数很大的时候,基本上能够呈现正态分布的特征,我们可以把它当成一个随机数序列来使用。

但是,当我们重复执行这个程序时,仔细观察可以发现,每次执行程序产生的数字序列是完全相同的,如下图所示。这是怎么回事呢?

原来,这个所谓的随机数序列实际上是以某个称为种子的数为基础,根据某个复杂的公式推算出来的,只能称为伪随机数字序列。

当计算机正常开机后,这个种子的值是预定了的,默认为1,所以在一台计算机的一次开机之后产生的默认伪随机序列总是相同的。

C语言中,还可以利用随机函数random()产生伪随机数序列,但random()函数不是ANSI C标准,random函数不能在gcc,vc等编译器下编译通过。

二、如何产生不可预见的随机数序列

要想产生不可预见的随机数序列,关键在于如何使rand()获得每次不同的种子数。什么样的数是永远不会重复的?那当然是时间啦,每一次运行计算机的时间是永远不相同的。

C语言还提供了一个产生随机种子数的函数srand(),将它与rand()函数相配合,就能达到这个目的。

程序中使用这二个函数的工作过程如下:

1)首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535

2)然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(032767之间)

3)根据需要多次调用rand(),从而不间断地得到新的随机数;

4)无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。

    下面是产生10个取值范围为0~32767之间的随机数的程序:

#include

#include

#include

void main( void )

{

       int i;

       srand( (unsigned)time(NULL));          //初始化随机数

    for( i=0; i<10; i++ )

          printf(" %d", rand());

       printf("\n");

}

三、如何产生设定范围内的随机数序列 

    rand()函数产生的随机数取值范围是0~rand_max(通常为0~32767),怎样才能产生从X~Y的随机数序列呢?

    XY,有YX1个数,所以要产生从XY的数,只需要这样写:

    k=rand()%(Y-X+1)+X;

就可以产生从XY的随机数序列了。

下面的程序可以产生2位正整数的随机数序列

#include

#include

#include

void main( void )

{

       int i;

       srand( (unsigned)time(NULL));

     for( i=0;  i<10;  i++ )

          printf(" %d", rand()�+10);

        printf("\n");

}

四、如何产生不重复的随机数序列

1)在具有100个元素的整型数组a中,将a[1]~a[99]赋予取值范围为1~99的随机数,所有元素的值不得重复。

在声明数组时,将所有元素的初值均赋为0,然后在每次for循环中随机地生成一个1~99范围内的下标,并判断该下标所定义的元素值是否为0,若为0,说明这个元素是空的,则把当前的循环控制变量i的值赋给它;若不为0,则说明这个元素已被赋值,于是在while循环中随机地寻找下一个空元素。

虽然i的值是顺序递增的,但它赋给的数组元素下标却是随机的,所以在保证了不重复的前提下,它的出现位置具有随机性,所以满足了題意要求。这种算法减少了大量的比较操作,时间和空间的效率都比较高。

#include

#include

#include

 

void main()

{          int i, m;

       int a[100]={0};                                        // 声明数组时将所有元素赋初值为0

       srand((unsigned)time( NULL ));

       for(i=1;  i<=99;  i++)

       {

        while(a[m=rand()0+1]);                // 随机地寻找一个初值为0的元素

        a[m] = i;                                            // 将不重复的i赋给这个元素

       }

    for(i=1;  i<=99;  ++i)

       {          printf("M", a[i] );

              if(i==0 || i>=99)  printf("\n");

       }

}

2)生成100个不重复的整数,取值范围为100~299,并保存在数组a中。

       算法分析:

利用随机函数rand()生成一个随机数temp之后,将它与数组a中已赋值的m个元素依次比较,如果都不重复,就把它作为一个新的元素添加到数组a中,作为已赋值元素的第m+1个元素。如果发现有重复,则重新生成一个随机数,再与前m个元素进行比较。

随着计算的进行,数组a中已赋值元素数m越大,需要进行比较的次数就越多,计算量也就越大。

#include

#include

#include

 

void main()

{          int i, m=0,temp,flag;

       int a[100]={0}; 

       srand((unsigned)time( NULL ));

       while(m<100)                                    // 是否已生成100个不重复元素?

       {     temp=rand() 0+100;               // 生成一个随机数temp

              flag=1;                                       // 假定temp与先前生成的所有数不重复

              for(i=0; i<=m; i++)                      // temp依次与先前生成的所有数比较

              {     if(a[i]==temp)                      // 若发现重复,修改标志,退出循环

                     {     flag=0;

                            break;

                     }

              }

              if(flag)                                       // 若确实与先前生成的所有数都不重复

              {     a[m] = temp;                       // 把这个数作为数组a的第m个元素

                     m++;                                  // 元素数加1

              }

       }

    for(i=0; i<=99; i++)

       {          printf("M", a[i] );

              if((i+1)==0 || i>=99) printf("\n");

       }

}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有