C语言解决随机数问题


 http://blog.sina.com.cn/s/blog_5348dc050100axzd.html 

        在有些程序中我们需要产生一些随机数,C语言中的随机数问题可以用<stdlib.h>中的rand()函数解决。
        如程序1: 

//  C语言解决随机数问题。
//  程序1。

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int i=1;

    printf("RAND_MAX = %d\n",RAND_MAX);
    for(;i<=20;i++)
    {
        printf("%10d",rand());
    }
    printf("\n");
    getchar();
    return 0;
}

      在这个程序中rand()函数用来生成一个随机数,rand()函数的原形位于<stdlib.h>中,函数的返回值是一个0~RAND_MAX的无符号整型, rand_max是<stdlib.h>中定义的一个符号常量(RAND_MAX is the maximum value that may be returned by rand.The minimum is zero.)  标准C规定至少要32767,故而0≤rand()≤RAND_MAX 。 

        在这个程序中,可以看到产生的随机数范围在0 ≤ rand() ≤ RAND_MAX,而有时候我们需要将随机数的范围缩小,例如用来模拟骰子的点数,范围就在1~6之间,此时我们可以参照以下程序:

// C语言解决随机数问题。
// 程序2,生成1~6之间的随机数。

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int i=1;

    for(;i<=20;i++)
    {
        printf("%10d",1+rand()%6);
        if(0==i%5)
            printf("\n");
    }
    printf("\n");
    getchar();
    return 0;
}

    在这个程序中我们采用取余的方式来进行比例缩放, rand()%6 用来产生0~5之间的随机数,然后(1+rand()%6)就可以产生1~6的随机数.

    对以上两个程序多次运行可以发现:程序运行的结果总是相同的!程序的结果具有可再现性,这种可再现性也表明了这两个程序运行的正确性,因为rand()函数产生的”随机数”是一个伪随机数,需要对他进行随机化(Randomizing)

    Srand()函数配合rand()函数使用可以实现随机数的生成, srand()需要外界提供一个无符号整数用来做产生随机数的种子,”种瓜得瓜,种豆得豆”种子不一样产生的随机数也就不一样,种子一样,产生的随机数也就一样。srand()函数也是<stdlib.h>中的函数。

// C语言解决随机数问题
// 程序3,随机化处理。

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int i=1;
    unsigned seed;

    printf("Please input the seed  ");
    scanf("%u",&seed);
    srand(seed);
    for(;i<=20;i++)
    {
        printf("%10d",1+rand()%6);
        if(0==i%5)
            printf("\n");
    }
    system("PAUSE");
    return 0;
}

    可以看到输入的种子一样,产生的随机数列就一样。

    我们可以通过利用系统时间作为seed从而来产生随机数。

// C语言解决随机数问题。
// 程序4, 系统时间作为seed。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
    int i=1;
    srand(time(NULL));
    for(;i<=20;i++)
    {
        printf("%10d",1+rand()%6);
        if(0==i%5)
            printf("\n");
    }

    system("PAUSE");
    return 0;
}

    函数time()将返回以秒为单位的从1970年1月1日午夜开始到现在所经历的时间,返回的时钟值以字符串的形式显示出来,但是实参NULL将屏蔽掉这个功能,又说:time()通常的参数是一个time_t类型对象的地址,那种情况下,时间也存在那个地址中,然而可以提供空指针来作为参数,此时时间值仅通过返回值机制提供。

    另外如果种子是个固定的或者种子的范围比较有规律,生成的随机数也同样有规律可言的。

    把种子取成系统当前的时间或者日期或者随时都不同的数字,比如GUID

srand((unsigned)time(NULL));

    程序执行的CPU时间较快,调用time函数获取的时间精度却较低(55ms),这样循环体内每次产生随机数用到的种子数都是一样的,因此产生的随机数也是一样的。可以用:

srand((unsigned)timeGetTime());//产生随机数种子

    这样可以使得每次产生的随机数序列不同。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。

 

    这些都是伪随机数,也可以用自己编写的随机数生成函数:

// C语言解决随机数问题。
// 程序5, 自行编写的随机数生成和随机化函数。

#include<stdio.h> 

static unsigned long int next = 1;   //next是一个具有内部链接的文件作用域变量
int rand(void)
{
    next = next *1103515245 + 12345;
    return (unsigned int)(next/65536)%32768;
}
 
void srand(unsigned int seed)
{
    next = seed;    
}
 
int main(void)
{
    int i=1;
    unsigned seed;

    printf("Please input the seed  ");
    scanf("%u",&seed);
    srand(seed);

    for(;i<=20;i++)
    {
        printf("%10d",1+rand()%6);
        if(0==i%5)
            printf("\n");
    }

    system("PAUSE");
    return 0;
}

        以上产生随机数的函数和方法仅仅适用于对于不太严格的程序中,因为可以根据程序运行的统计结果来得出规律。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值