• 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函数中,果然适当的理解比瞎实践有用很多。

  • 相关阅读:
    运动第六课时
    java获取json数组格式中的值
    高性能网站建设进阶指南解说 新风宇宙
    检查素数的正则表达式 新风宇宙
    A*算法(游戏中寻路算法)特别奉献php实现源码? 新风宇宙
    几个值得放在common中的函数 新风宇宙
    以x%的概率执行某段代码 新风宇宙
    战场每步操作记录的存放方法 新风宇宙
    我的个人简历(最近离职找工作) 新风宇宙
    关于腾讯截取字符串问题 新风宇宙
  • 原文地址:https://www.cnblogs.com/VingB2by/p/10127610.html
Copyright © 2020-2023  润新知