Day23:C++时间管理/随机数/引擎适配器

目录

一、时间段

        1.表示时间间隔,可以是秒,分钟,小时,微妙,毫秒,纳秒

        2.创建: 

         3.常用的场景:线程的睡眠

         4.时间段之间的相加减操作

二、时钟

        1. 时钟类共用的一些函数

                ①static time_point now() 获取当前时间点

                ②static time64_t to_time_t(const time_point x);

                        //类型转化:至 time_t

                ③time_point  from_time_t(time_t x); 

                         //类型转化:至time_point

        2.system_clock:获取时间点(time_point->在system_clock类中),需要转换为time_t才能显示出来

        3.steady_clock: 计时 类似秒数

        4. high_resolution_clock: 高精度时钟

三、时间转化        

四、种子序列  seed_seq 类似于一种容器

五、 随机数&引擎适配器

1. 四种引擎适配器:

 2.相关操作:        

        ①C++中生成随机数

        ②分布方式和引擎的方式

        ③了解部分 (适配器的实例化->产生随机数  等效于  直接用内置引擎)


一、时间段

        1.表示时间间隔,可以是秒,分钟,小时,微妙,毫秒,纳秒

#include<chrono>

        2.创建: 

        一般使用的时候,不建议用duration类来使用,直接使用别名即可。
        using nanoseconds  = duration<long long, nano>;        //纳秒
        using microseconds = duration<long long, micro>;    //微妙
        using milliseconds = duration<long long, milli>;    //毫秒
        using seconds      = duration<long long>;            //秒
        using minutes      = duration<int, ratio<60>>;        //分钟 ->ratio<60>是分子除以分母,本处就是1min
        using hours        = duration<int, ratio<3600>>;    //小时

    chrono::duration < long long,ratio<60>> dur;
    //相当于创建1min (ratio是一个60/1默认->60s)
	chrono::hours h(1);            //1h
	chrono::minutes m(1);          //1min

         3.常用的场景:线程的睡眠

#include<thread>

                注意:C++中sleep_for是对文本进行相关的重载过了,所以用下面两种方式进行休眠会更加方便。

    cout << "延时1秒钟" << endl;
	this_thread::sleep_for(chrono::seconds(1));   //延时1描述
	cout << "延时3秒钟" << endl;
	//直接使用文本重载的形式使用时间,没必要用类去构造函数
	this_thread::sleep_for(1s);
	cout << "延时500毫秒" << endl;
	this_thread::sleep_for(500ms);
	//cout << "延时1小时" << endl;
	//this_thread::sleep_for(chrono::hours(1));

         4.时间段之间的相加减操作

                ①时间段之间允许直接进行运算符 ,不需要大家做一个转换操作

                ②//chrono::minutes res2 = h1 - sec1;×   用minute来接收是不被允许的!

                         /*如何正常接收并转换,见第三部分,时间转换 duration_cast 亦或是采用                                     chrono::duration<double,ratio(...)>的实例化对象来接收即可!*/

                ③//count函数可以打印时间间隔多少

	//时间段之间允许直接进行运算符 ,不需要大家做一个转换操作
	chrono::hours h1(1);
	chrono::seconds sec1(100);
	chrono::seconds result = h1 - sec1;
	//chrono::minutes res2 = h1 - sec1;用minute来接收是不被允许的!!!
    /*如何正常接收并转换,见第三部分,时间转换 duration_cast*/
	//count函数可以打印时间间隔多少秒
	cout <<"s:" << result.count() << endl;

输出:s:3500

二、时钟

#include<chrono>
#include<iomanip>    /*put_time*/
#include<thread>

        1. 时钟类共用的一些函数

                ①static time_point now() 获取当前时间点

                ②static time64_t to_time_t(const time_point x);

                        //类型转化:至 time_t

                ③time_point  from_time_t(time_t x); 

                         //类型转化:至time_point

        2.system_clock:获取时间点(time_point->在system_clock类中),需要转换为time_t才能显示出来

void test_system_clock() 
{
	//1.获取时间点
	chrono::system_clock::time_point result = 
		chrono::system_clock::now();
	//2.获取时间点,转换为可以显示的时间:time_t
	time_t m_tm = chrono::system_clock::to_time_t(result);
	//time_t  : 时间戳 离1970多少秒
	//打印法一:转换为正确的时间打印处理,ctime:转换为字符串
	cout << ctime(&m_tm) << endl;
    //打印法二:利用利用iomanip中put_time函数(参数类型是tm->localtime转换)
	std::tm* p = localtime(&m_tm);
	cout << "格式化时间:" << put_time(p, "%F %T") << endl; 
	/*其余的时间格式控制字符串,见cplusplus官网,搜put_time()*/
	cout <<"时间段打印时间戳:" << result.time_since_epoch().count() << endl;
	chrono::system_clock::time_point end =
		chrono::system_clock::now();
	auto duration = end-result;
	cout << duration.count() << endl;//单位:ns纳秒
}

 输出:

Sun Jul  3 07:30:43 2022

格式化时间:2022-07-03 07:30:43
时间段打印时间戳:16568046436160916
53405                                        //ns

        注意:上述时间点(time_point)和时间戳(time_t)的区别与转化。

                       以及时间点(time_point)的打印需要先调用time_since_epoch()再调动count()

        3.steady_clock: 计时 类似秒数

void test_steady_clock() 
{
	chrono::steady_clock::time_point startTime = chrono::steady_clock::now();
	this_thread::sleep_for(1s);
	auto endTime = chrono::steady_clock::now();/*直接用auto推断偷懒*/
	auto time = endTime - startTime;
	cout <<"耗时:" << time.count() <<"ns" << endl;
	chrono::duration<double,ratio<1>> sec = endTime - startTime;
	cout << "耗时:" << sec.count() << "s" << endl;
}

输出:

耗时:1007550200ns
耗时:1.00755s

注:如何将时间间隔的ns自动转化为s秒。                

                ->chrono::duration<double,ratio<1>> sec =endTime-startTime; 

                        ---同理,将ratio<1>改成ratio<60>就是以min作为单位。

        4. high_resolution_clock: 高精度时钟

void test_high_resolution_clock() 
{
	//时间间隔和计算机运行速度有关,和什么精度时钟无关
	//只是说高的精度 更贴近实际时间。
	auto startTime = chrono::high_resolution_clock::now();
	this_thread::sleep_for(1s);
	auto endTime =chrono::high_resolution_clock::now();
    /*上面这句话等效于:
    chrono::high_resolution_clock::time_point endTime =
     chrono::high_resolution_clock::now();*/
	auto time = endTime - startTime;
	cout << "耗时:" << time.count() << "ns" << endl;
	chrono::duration<double, ratio<1>> sec = endTime - startTime;
	cout << "耗时:" << sec.count() << "s" << endl;
}

输出:

耗时:1006585200ns
耗时:1.00659s

用法基本相同(类似)。 

三、时间转化        

        1.duration_cast:不属于duration 类

                浮点时长和整数时长之间可以直接隐式转化,其他情况要使用这个函数做转换

void test_duration_cast() 
{
	chrono::high_resolution_clock::time_point
		start = chrono::high_resolution_clock::now();
	this_thread::sleep_for(1s);
	auto end= chrono::high_resolution_clock::now();
	//当end-start无法赋值的时候,就记得duration_cast即可。
	chrono::milliseconds dtime 
		= chrono::duration_cast<chrono::milliseconds>(end - start);
	/*milliseconds->毫秒ms*/
	cout << dtime.count()<<"ms" << endl;

	//浮点形隐式转换->无需强转(直接隐式转化,end和start均是long长整型)
	chrono::duration<double, ratio<1, 1000>> dtime2 = end - start;
	cout << dtime2.count() << "ms" << endl;
}

输出:

1007ms
1007.1ms

        2.time_point_cast :不属于time_point

                (使用情况)存在精度丢失的ratio转换,就必须使用time_point_cast做转换

//辅助函数
template <class Duration>
void print_ms(const chrono::time_point<chrono::high_resolution_clock, Duration> time_point) 
{
	cout << time_point.time_since_epoch().count()<<"ms" << endl;
}
void test_time_point_cast() 
{
	using TIMEMS = chrono::time_point<chrono::high_resolution_clock, chrono::milliseconds>;
	TIMEMS time_point_sec(6s);  //chrono::seconds(6) 替换6s
	//秒到毫秒(不存在精度丢失)
	TIMEMS time_point_ms(time_point_sec);
	print_ms(time_point_ms);

	time_point_ms = TIMEMS(6789ms);
	using TIMESEC = chrono::time_point<chrono::high_resolution_clock, chrono::seconds>;
	//毫秒到秒赋值(会有精度丢失,要用time_point_cast)
	TIMESEC time_sec =chrono::time_point_cast<chrono::seconds>(time_point_ms);
    //强转到seconds
	print_ms(time_sec);
}

输出:

6000ms
6ms

四、种子序列  seed_seq 类似于一种容器

头文件:

#include<random>
#include<functional>  //仿函数

类似C语言srand函数 ,用来设置范围

  • size() 检测种子个数

  • generate()函数 (通过内部的算法计算后,填充某个容器)

  • param()函数

    #include <iostream>
    #include <random>
    #include <functional>
    #include <array>
    using namespace std;
    int main() 
    {
    	seed_seq seed = { 1,3,4,5,6,7,8 };
    	cout <<"size:" << seed.size() << endl;
    	array<int, 7> data;
    	seed.param(data.begin());
    	for (auto v : data) 
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    	//array<int, 7> data2;
    	//seed.generate(data2.begin(), data2.end());
    	//for (auto v : data2) 
    	//{
    	//	cout << v << "\t";
    	//}
    	cout << endl;
    	return 0;
    }

输出:

size:7
1       3       4       5       6       7       8

五、 随机数&引擎适配器

微软文档  

1. 四种引擎适配器:

  • shuffle_order_engine: 乱序随机数引擎适配器

  • independent_bits_engine: 独立位随机数引擎适配器

  • discard_block_engine: 丢弃块随机数引擎适配器

  • default_random_engine: 默认的随机数引擎(最常用)

 2.相关操作:        

        ①C++中生成随机数

    default_random_engine  e;
	e.seed((size_t)chrono::high_resolution_clock::now().time_since_epoch().count());
	//等效这个:e.seed((size_t)time(NULL));     ->c语言风格->显然更好用、简洁
	for (int i = 0; i < 3; i++) 
	{
        //仿函数的方式生成随机数!!!
		cout<<"随机数:" << e()%10 << endl;  //通过取余固定范围
	}
	cout <<"max:"<< e.max() << endl;        //生成随机数的上界
	cout << "min:" << e.min() << endl;      //生成随机数的下界

输出: 

随机数:8
随机数:5
随机数:5
max:4294967295
min:0

        ②分布方式和引擎的方式

        分布方式实际上也是一个需要实例化的仿函数,传入参数即默认引擎e,使得能够产生初始化区间内的随机数!!!

    default_random_engine  e;
    uniform_int_distribution<int>  duration(1, 6);
	cout <<"uniform:"<< duration(e) << endl;
	auto randDom = bind(duration, e);
	cout << "sum:" << (randDom() + randDom() + randDom()) << endl;

输出:

uniform:5
sum:8

注:本处采用bind函数,将仿函数duration的唯一一个参数绑定为e

       ③了解部分 (适配器的实例化->产生随机数  等效于  直接用内置引擎)

                注:引擎就是适配器的实例化 使用时直接用,不需要进行传参

                (适配器的实例化有时会传入很多参数)(此部分直接查文档)

                        ->直接用引擎的别名->但实际上用的最多的还是直接用default_random_engine

	//3.1 线性同余  //x=(x*a+c)%m;
	//适配器实例化 产生随机数
	linear_congruential_engine<unsigned int, 1, 2, 8> ee;
	e.seed((size_t)time(nullptr));//采用c语言风格的种子,一样可以
	cout <<"线性同余:"<< ee() << endl;

	mersenne_twister_engine<unsigned int, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1> em;
	mt19937_64 eeee;//直接使用引擎,一般不采用上述的做法
	cout << "梅森旋转:" << eeee() << endl;

输出:

线性同余:3
梅森旋转:14514284786278117030

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ocean__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值