C++产生随机数理解

rand:

rand()函数需要用到头文件#include<cstdlib>,根据种子值返回一个伪随机函数,为什么说是伪随机,是因为程序都是根据一定的算法来实现的,在不设置srand时,默认为调用的是srand(1),由于每次都是一样的种子值,使得每次运行产生的结果都是相同的。

#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
    int Rand[10];
    for(int i=0;i<10;i++)
        Rand[i]=rand();
    for (int i = 0; i<10; i++)
        cout<<Rand[i]<<" ";
    system("pause");
}

每次运行结果都是相同:

srand:

通过修改种子值srand可以使得每次产生的随机数不同,但是还是会有一定的规律,为了产生更加随机的随机数,一般是采用时间作为种子数

srand((unsigned)time(NULL));//需要头文件#include<ctime>

修改后的代码如下:

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int main()
{
    int Rand[10];
    srand((unsigned)time(NULL));
    for(int i=0;i<10;i++)
        Rand[i]=rand();
    for (int i = 0; i<10; i++)
        cout<<Rand[i]<<" ";
    system("pause");
}

可以发现每次运行的结果都不一样了。

通式:

如果要去一定范围内的值,则要用到通式k=x+rand()%(y-x+1),k即为所求范围内随机生成的数,rand()%a的结果最大为a-1。

整数例子:

[0,10]:rand()%11

[1,11]:1+rand()%11

(0,10):1+rand()%9

浮点数例子:

[0.0,1.0]=(rand()%10)*0.1

函数:

上述例子产生随机数都是在main函数中,但是有时候我们希望把产生随机数的函数封装起来,适当地调用,但是错误的编写就会导致每次出来的随机数都是相同的。

错误例子

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int GetRand() {
    int Rand;
    srand((unsigned)time(NULL));
    Rand = rand()%10;
    return Rand;
}
int main()
{
    int Rand[10];
    for(int i=0;i<10;i++)
        Rand[i]=GetRand();
    for (int i = 0; i<10; i++)
        cout<<Rand[i]<<" ";
    system("pause");
}

正确例子:

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int GetRand() {
    int Rand;
    Rand = rand()%10;
    return Rand;
}
int main()
{
    int Rand[10];
    srand((unsigned)time(NULL));
    for(int i=0;i<10;i++)
        Rand[i]=GetRand();
    for (int i = 0; i<10; i++)
        cout<<Rand[i]<<" ";
    system("pause");
}

产生这个的原因很简单,错误的例子中每一次进入for循环都是重新设置了一次种子值,由于程序运行速度十分快,srand是以秒作为时间单位,这就是相当于每一次进入循环的重新设置了相同的种子值,所以得出的结果也就是相同了。

而在正确的例子中,把设置种子值调用在for之前,也就相当于把后面的十次循环按照第一次设置的种子值产生序列,自然值也就不同。

处理方法并不唯一,另一种处理方式是利用类结构体:

class RandomNumber {
public:
    RandomNumber() {
        srand((unsigned)time(NULL));
    }
    int GetRand() {
        int RandNumber;
        RandNumber = rand()%301;
        return RandNumber;
    }
};

通过构造函数在创建类时设置好种子值,后序调用自然也会按照该种子值设定好的序列来进行。

总结:

一般情况下,在程序中只要写一次srand((unsigned)time(NULL))即可,需要注意该语句是否处在循环中。

PS:以前不懂都是把srand的语句瞎换位置,不用就把语句直接写mian函数中,果然适当的理解比瞎实践有用很多。

posted @ 2018-12-16 19:12  VingB2by  阅读(367)  评论(0编辑  收藏  举报