• C++相关:部分标准库特殊设施


    C++ tuple(元组)

    tuple是C++11新标准里的类型。它是一个类似pair类型的模板。pair类型是每个成员变量各自可以是任意类型,但是只能有俩个成员,而tuple与pair不同的是它可以有任意数量的成员。但是每个确定的tuple类型的成员数目是固定的。

    声明如下

      tuple<int,int,float> tp(1,2,6.2);

    取值

    cout << get<0>(tp) << endl; //输出1
    cout << get<1>(tp) << endl; //输出2
    cout << get<2>(tp) << endl; //输出6.2

    tuple的基本操作

    操作 说明
    make_tuple(v1,v2,v3,v4…vn) 返回一个给定初始值初始化的tuple,类型从初始值推断
    t1 == t2 当俩个tuple具有相同数量的成员且成员对应相等时
    t1 != t2 与上一个相反
    get<i>(t) 返回t的第i个数据成员
    tuple_size<tupletype>::value 给定类型的tuple中成员的数量

    C++随机数

    定义在头文件random中的随机数库通过一组协作的类来解决这些问题:随机数引擎类和随机数分布类。
    默认随机数引擎default_random_engine,基本使用如下:
        default_random_engine e;
        cout << "默认范围:" << e.min() <<"——" << e.max() << endl;
        for(int i = 0;i < 10;++i)
        {
            cout << "生成的随机数(默认种子):" << e() << endl;
        }
    基本操作
    Engine e;                 //默认构造函数并使用默认种子
    Engine e(s);             //使用整型值s作为种子
    e.seed(s);                //使用种子s重置引擎的状态
    e.min();                   //引擎生成的值的范围
    e.max();                  
    Engine::result_type  //此引擎生成的unsigned整型类型
    e.discard(u);            //将引擎推进u步;u的类型为unsigned long long

    分布类型和引擎

    为了得到一个指定范围内的数,我们需要将分布对象和引擎对象组合使用,这种组合又称为随机数发生器。

    //生成0到9之间(包含)均匀分布的随机数
    uniform_int_distribution<unsigned> u(0,9);
    default_random_engine engine;  //生成无符号随机整数
    for(int i = 0;i < 10;i++)
    {
        //将u作为随机数源
        //每个调用返回指定范围内的服从均匀分布的值
        //这里讲引擎本身传给u,原因是某些分布可能需要调用引擎多次才能得到一个值
        //如果写成u(e())会导致编译错误
        cout << u(e) << " ";
    }

    生成不同的随机数序列

    一个给定的随机数发生器一直会生成相同的随机数序列,为了生成与之前不同的序列,可以将引擎和分布对象定义为static的

    static uniform_int_distribution<unsigned> u(0,9);
    static default_random_engine engine;  

    但这种方法仅适用于局部的随机数发生器,另一种方法是调用系统时间函数time来作为发生器种子,这也是C中rand函数常使用的方法。声明如下:

    default_random_engine el(time(0));

    time返回从特定时刻到当前经过了多少秒,它接受单个指针参数,指向用于写入时间的数据结构,如果为空则直接返回时间。

    但是time返回以秒计的时间,因此这种方法仅适用于生成种子的间隔为秒级或者更长的应用,如果程序的自动过程反复运行的频率过高,则可能多次使用的都是相同的种子。

    其他随机数分布

    生成随机实数

    在C中,从rand获得一个随机浮点数的常用方法是用rand()的结果除以RAND_MAX,但这种方法并不正确,原因是随机整数的精度通常低于随机浮点数,这样一些浮点数永远不会生成。

    在C++中,可以使用uniform_real_distribution类来处理从随机整数到随机浮点数的映射。代码如下

    default_random_engine e;
    uniform_real_distribution<double> u(0,1);
    for(int i = 0;i < 10;i++)
    {
         cout << u(e) << " ";
    }
    

     输出如下:

    生成非均匀分布的随机数

    标准库提供了20余种分布类型,具体可参考C++ Random 。

    这里以伯努利分布为例,以下代码模拟了一个游戏中决定玩家和电脑谁先行动的情景,不停输入y可以看到随机生成两种结果的一种——电脑先走或者玩家先走。

    string resp;
        default_random_engine e; //e应保持状态,所以必须在循环外定义
        bernoulli_distribution b; //默认对半的机会
        do
        {
            bool first = b(e);   //如果为true程序先走
            cout << (first?"We go first":"You go first") << endl;
            cout << "Gaming............" << endl;
            cout << "Game over.Input y to restart or exit" << endl;
        }while(cin >> resp && resp[i] == 'y')

    如果想给玩家一点作弊的小后门,可以调整先行一方的概率

    bernoulli_distribution b(.45); //减少程序先行的概率 

    这样分布情况就为(0.45/0.55) 

    参考资料

    《C++ Primer 第5版》 电子工业出版社    作者:【美】  Stanley B. Lippman  && Josee Lajoie && Barbara E.Moo

      伯努利分布

  • 相关阅读:
    Day 69
    Day 68
    Day 67
    Day 66
    Day 65
    Day 64
    Day 63
    Day 62
    Day 61
    Day 60
  • 原文地址:https://www.cnblogs.com/0kk470/p/7908257.html
Copyright © 2020-2023  润新知