C/C++基础----标准库几个工具库tuple,bitset,正则表达式,随机数,IO库
tuple
tuple可以有任意多个成员
默认初始化,值初始化
构造函数是explicit,必须直接初始化
make_tuple(v1,v2,…,vn)
get<i> (t) 返回第i个数据成员的引用,t是左值则返回左值引用,右值则返回右值引用
tuple_size<tupleType>::value 表示成员的数量
tuple_element<i,tupleType>::type 表示给定tuple类型中指定成员的类型
为了使用关系运算符,每对成员使用运算符比较都是合法的。
如果tuple定义了<和==,则可以将tuple序列传递给算法,并且可以在无序容器中讲tuple作为关键字。
bitset
使得位运算的使用更加容易,并且能够处理超过最长整型类型大小的位集合。
具有固定的大小,定义时必须给出。编号从0开始是低位。
默认构造,constexpr,每一位均为0
直接构造,将unsigned long long值u的低n位拷贝,如果不足n位高位被置0
bitset<n> b(s, pos, m, zero, one) string s的pos位置开始拷贝m个字符,s只能包含zero和one。pos默认0,m默认string::npos,zero默认’0’
也可以从指向的字符数组中拷贝字符,如果未提供m则必须是c风格字符串。如果提供了m从pos开始至少有m个zero或one
字符串中下标最小的字符对应高位。
函数 | 操作 |
---|---|
b.any() | b中是否存在置位 |
b.all() | 是否所有位都置位 |
b.none() | 是否不存在置位的位 |
b.count() | 位置的位数 |
b.size() | constexpr 返回b中的位数 |
b.test(pos) | 检查pos位置是否置位 |
b.set(pos,v) | 将pos位置设置为v,v默认true |
b.set() | 所有位置位 |
b.reset(pos) | 复位pos处 |
b.reset() | 所有位复位 |
b.flip(pos) | 改变pos处位的状态 |
b.flip() | 改变所有位的状态 |
b[pos] | 访问pos处的位;如果b是const,返回的是bool |
b.to_ulong() | 只能往大了转,否则抛出overflow_error |
b.to_ullong() | |
b.to_string(zero,one) 返回一个string | |
os<<b | |
is>>b | 当下一个不是1或0时,或已经读了size位时停止 |
正则表达式
- regex 正则表达式类
regex_match 判定整个输入序列与表达式是否匹配
regex_search 判定是否有子串与表达式匹配,找到一个就停止
regrex_replace 使用给定格式替换一个表达式
sregex_iterator 迭代器适配器,调用search来遍历一个string中所有的子串
smatch 容器类,保存搜索的结果
ssub_match string中匹配的子表达式的结果
regrex_search参数 (seq, m, r, mft) 在seq序列中查找regrex对象r中的正则表达式,匹配的结果保存在m,mft是一个可选的regex_constants::match_flag_type值,会影响匹配过程
regex_match参数 (seq, r, mft)
regex r(re, f) re是一个正则表达式,f是标志,默认为ECMAScript
标志定义在regex和regex_constants::syntax_option_type中
icase 在匹配过程中忽略大小写
nosubs 不保存匹配的子表达式
optimize 执行速度优先于构造速度
ECMAScript 使用ECMA-262指定的语法
basic 使用POSIX基本的正则表达式语法
extended POSIX扩展
awk POSIX版本的awk语言的语法
grep POSIX版本的grep语法
egrep POSIX版本的egrep语法
- 特殊字符
[^c]任意不是c的字符
ECMAScript中[[:alpha:]]表示匹配任意字母
+表示一个或多个
*表示零个或多个
string pattern(“[^c]ei”);
pattern = “[[:alpha:]]*” + pattern + “[[:alpha:]]*”;
regex r(“[[:alpha:]]+\\.(cpp|cxx|cc)$”, regex::icase);
字符点.通常匹配任意字符
可以在前面放一个反斜线来去掉其特殊意义
又因为反斜线也是C++中的特殊字符,所以需要再使用一个反斜线得到普通反斜线字符
- 使用
一个正则表达式的语法是否正确是在运行时解析的。
如果存在错误,会抛出regex_error
catch (regex_error e)
{cout<<e.what()<<”\ncode: ”<<e.code()<<endl;}
构造或者赋值一个regex对象是非常耗时的,最小化开销应该避免创建不必要的regex。
特别是在循环中使用的话,应该在外部创建。
- RE库类
string regex、smatch、ssub_match和sregex_iterator
const char* regex、cmatch、csub_match和cregex_iterator
wstring wregex、wsmatch、wssub_match和wsregex_iterator
const wchar_t* wregex、wcmatch、wcsub_match和wcregex_iterator
迭代器在构造时会执行一次search,后面每递增一次从当前位置开始调用search
sregex_iterator it(b, e, r);
sregex_iterator end; //空的表示尾后迭代器
除了得到匹配的结果,我们还能够得到匹配结果的更多细节信息。
it->str()
it->prefix().str() xxxeixxx it->suffix().str()
- smatch操作
(同样适用于cmatch、wsmatch、wcmatch和对应的csub_match、wsub_match和wcsub_match)
操作 | 描述 |
---|---|
m.ready() | 已经通过搜索设置了m则返回true |
m.size() | 如匹配失败,则返回0;否则返回匹配子表达式的个数 |
m.empty() | size为0 则true |
m.prefix() | 一个ssub_match对象,表示当前匹配之前的序列 |
m.suffix() | 之后的序列 |
m.format(…) | 生成格式化输出 |
以下n默认0且必须小于m.size().索引0表示整个匹配 | |
m.length(n) | 匹配结果中第n个子表达式 |
mposition(n) | 第n个子表达式距序列开始的距离 |
m.str(n) | 第n个子表达式的string |
m[n] | 对应第n个子表达式的ssub_match对象 |
m.begin() m.end() | 表示m中sun_match元素范围的迭代器 |
m.cbegin() m.cend() |
- 使用子表达式
通常用括号表示子表达式
regex r(“[[:alpha:]]+\\.(cpp|cxx|cc)$”, regex::icase);
如上面的例子在search之后
results.str(1)表示第一个子表达式,即文件名部分
- ECMAScript正则表达式的一些特性
\{d}表示单个数字,\{d}{n}表示n个数字(如\{d}{3})
方括号中的字符集合表示匹配这些字符中任意一个(如[-. ]匹配短横、点或一个空格)。点在括号中没有特殊含义
后接一个’?’的组件是可选的( \{d}{3}[-. ]?\{d}{4} )
反斜线表示一个字符本身而不是其特殊意义。由于括号是特殊字符,所以需要加\(和\)
C++中反斜线是特殊字符,所以每次出现的地方都要两个\\
“(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})”
(\\()? 表示区号部分可选的左括号
(\\d{3}) 表示区号
(\\))? 表示区号部分可选的右括号
([-. ])? 表示可选的分隔符
(\\d{3}) 表示3位号码
([-. ]?) 表示可选的分隔符
(\\d{4}) 表示号码的最后4位
- 子匹配操作
操作 | 描述 |
---|---|
matched | 指出ssub_match是否匹配了 |
first | 指向匹配序列首元素的迭代器 |
second | 指向匹配序列尾后位置的迭代器 |
length() | 子匹配序列的大小 |
str() | 返回一个包含输入中匹配部分的string,未匹配则空串 |
s=ssub | ssub_match对象ssub转换为string对象 |
- 当希望查找并替换时,可以使用regex_replace
m.format(dest, fmt,mft)
m.format(fmt, mft)
使用格式化字符串fmt生成格式化输出。第一个版本写入迭代器dest指向的目的位置。fmt可以是string,也可以是表示字符数组范围的一对指针。
第二个版本返回一个string,fmt可以是string,也可以是一个指向空字符结尾的指针。
mft默认format_default
regex_replace(dest, seq, r, fmt, mft)
regex_replace(seq, r, fmt, mft)
遍历seq查找匹配的子串。seq既可以是string也可以是c风格字符串。fmt既可以是string也可以是c风格字符串。
mft默认match_default
- 使用$后跟子表达式的索引号来表示一个特定的子表达式
string fmt=”$2.$5.$7”;//将号码格式改为ddd.ddd.dddd
regex r(phone);
string number = “(905) 555-1800”;
cout<<regex_replace(number, r, fmt)<<endl;
- 匹配和格式化标志 regex_constants::match_flag_type
标志 | 描述 |
---|---|
match_default | 同format_dafault |
match_not_bol | 不将首字符作为行首处理 |
match_not_eol | 不将尾字符作为行尾处理 |
match_not_bow | 不将首字符作为单词首处理 |
match_not_eow | 不将尾字符作为单词尾处理 |
match_any | 如果存在多余一个匹配,则可返回任意一个匹配 |
match_not_null | 不匹配任何空序列 |
match_continuous | 匹配必须从输入的首字符开始 |
match_prev_avial | 输入序列包含第一个匹配之前的内容 |
format_default | 使用ECMAScript规则替换字符串 |
format_sed | 用POSIX sed规则替换 |
format_no_copy | 不输出输入序列中未匹配的部分 |
format_first_only | 只替换子表达式的第一次出现 |
随机数
以前都依赖rand函数来生成,此函数生成均匀分布的伪随机整数。每个数的范围都在0到一个系统相关最大值之间。
问题:需要不同范围的随机数,需要随机浮点数,需要非均匀分布的数。程序员为解决这些问题而试图转换的过程常常会引入非随机性。
标准库提供了随机数引擎类和随机数分布类来解决这些问题。
引擎类生成unsigned随机数序列,分布类使用引擎类生成指定类型的、在给定范围内、服从特定概率分布的随机数。
C++程序不应该使用rand,而应该使用default_random_engine类和恰当的分布类对象
可以通过调用引擎对象来生成原始随机数
default_random_engine e; cout<<e()<<endl;
引擎可以用整型值s作为种子 Engine e(s); e.seed(s);//重置引擎状态
e.discard(u) 将引擎推进u步
原始随机数通常不能直接使用,需要转换。所以用到分布类
uniform_int_distribution<unsigned> u(0, 9);//0到9之间(包含)均匀分布随机数
default_random_engine e;
cout<<u(e)<<endl;
分布类也是函数对象类,可以调用,接收一个引擎对象作为参数。注意是引擎对象本身,而不是其生成的值。
当我们说随机数发生器时,是指的引擎对象和分布对象的组合。
引擎生成整数在一个系统定义的范围内(我的系统0到4294967295)
rand生成范围0到RAND_MAX之间(我的系统0到32767)
每次返回相同的数值序列,在调试时非常有用,但是设计时必须考虑。
如是局部的可以定义为static,则每次调用都会推进。
种子是一个数值,引擎可以从序列中一个新位置重新开始生成随机数。
最常用的是调用系统时间time(在头文件<ctime>中),time接受单个指针参数,指向用于写入时间的数据结构。如果指针为空,则简单的返回时间。
因为time返回的是以秒计的时间,只适用于生成种子间隔秒级甚至更长的应用。
d.reset()//重置d的状态,不依赖与已经生成的值
uniform_real_distribution<double> u(0, 1); //生成均匀分布的随机实数,同样包含
非均匀分布随机数
标准库定义20中分布类型,见附录
正态 normal_distribution<> n(4, 1.5);
伯努利 bernoulli_ distribution b;//非模板,返回bool,true的概率为常数,默认0.5
IO库再探
格式控制、未格式化IO、随机访问
操纵符改变流的状态,通常改变后对后面所有IO都生效。不需要特殊格式时尽快恢复。
输出控制:控制数值输出形式,控制补白的数量和位置
浮点数默认:6位数字精度打印;没有小数部分则不打印小数点根据浮点数的值打印成定点十进制或科学计数法
调用IO对象的precision成员或setprecision操纵符来改变精度
precision接收一个int,将精度设置成此值,并返回旧精度值。或者不接受参数,返回当前精度值。setprecision接收一个参数设置精度。
scientific、fixed或hexfloat后,精度值时控制的小数点后位数,而默认是总的位数。
setw指定下一个数字或字符串值的最小空间
setfill可以指定一个字符替代默认的空格
setprecision设置精度
setbase设置整数输出进制
- 输入控制
默认:忽略空白符(空格、制表符、换行符、换纸符、回车符)
操纵符noskipws,读取空白符,skipws恢复
未格式化IO , 允许我们将一个流当做无解释的字节序列来处理
单字节低层IO操作
操作 | 描述 |
---|---|
is.get(ch) | 从is读取下一个字节存入字符ch中,返回is |
os.put(ch) | 将字符ch输出到os,返回os |
is.get() | 将is的下一个字节作为一个int返回 |
is.putback(ch) | 将字符ch放回is,返回is |
is.unget() | 将is向后移动一个字节,返回is |
is.peek() | 将下一个字节作为int返回,但是不从流中删除它 |
- 标准库保证我们可以退回最多一个值
返回int值可以返回文件尾标记,char范围内的字符都已经占了。标准库使用负值表示文件尾。<cstdio>中定义了名为EOF的const来检测返回的是否是文件尾。
int ch;
while((ch = cin.get() !=EOF)
cout.put(ch);
- 多字节底层IO操作
操作 | 描述 |
---|---|
is.get(sink, size, delim) | 从is中读取最多size个字节,保存在sink给出的字符数组中。直至遇到字符delim或者读满了size个或遇到文件尾。delim不读取,留在输入流中 |
is.getline(sink, size, delim) | 与上面的get类似,但是会读取并丢弃delim |
is.read(sink,size) | 读取最多size个字节,存入字符数组sink。返回is |
is.gcount() | 返回上一个未格式化读取操作从is读取的字节数 |
os.write(source, size) | 将字符数组source中size个字节写入os,返回os |
is.ignore(size, delim) | 读取并忽略最多size个字符,包括delim。size默认为1,delim默认为文件尾。 |
一般情况下,推荐更安全更高层的操作
- 流随机访问
随机IO本质上依赖于系统
IO类型维护一个标记来确定下一个读写操作要在哪里进行。
istream和ostream通常不支持随机访问
操作 | 描述 |
---|---|
tellg() | 返回一个输入流中标记的当前位置 |
tellp() | 输出流 |
seekg(pos) | |
seekp(pos) | 输出流 |
seekg(off, from) | 将一个输入流中,将标记定位到from前后off个字符的位置 |
seekp(off, from) | from可以是beg,cur,end |
流中只维护单一的标记,对于支持读写操作的流,在读写之间切换时,必须进行seek操作来重定位标记。
pos和off的类型分别是是pos_type和off_type,是机器相关的,定义在和
C/C++基础----标准库几个工具库tuple,bitset,正则表达式,随机数,IO库的更多相关文章
- c++标准之IO库
1.面向对象的标准库 2.多种IO标准库工具 istream,提供输入操作 ostream,提供输出操作 cin:读入标准输入的istream对象.全局对象extern std::istream ci ...
- 开箱即用 yyg-cli(脚手架工具):快速创建 vue3 组件库和vue3 全家桶项目
1 yyg-cli 是什么 yyg-cli 是优雅哥开发的快速创建 vue3 项目的脚手架.在 npm 上发布了两个月,11月1日进行了大升级,发布 1.1.0 版本:支持创建 vue3 全家桶项目和 ...
- [APUE]标准IO库(下)
一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中 ...
- [APUE]标准IO库(上)
一.流和FILE对象 系统IO都是针对文件描述符,当打开一个文件时,即返回一个文件描述符,然后用该文件描述符来进行下面的操作,而对于标准IO库,它们的操作则是围绕流(stream)进行的. 当打开一个 ...
- 文件IO函数和标准IO库的区别
摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...
- Bootstrap<基础十> 响应式实用工具
Bootstrap 提供了一些辅助类,以便更快地实现对移动设备友好的开发.这些可以通过媒体查询结合大型.小型和中型设备,实现内容对设备的显示和隐藏. 需要谨慎使用这些工具,避免在同一个站点创建完全不同 ...
- Atitit.atiInputMethod v2词库清理策略工具 q229
Atitit.atiInputMethod v2词库清理策略工具 q229 1.1. Foreigncode 外码清理1 1.2. 垃圾词澄清1 1.1. Foreigncode 外码清理 On ...
- C++ Primer 读书笔记: 第8章 标准IO库
第8章 标准IO库 8.1 面向对象的标准库 1. IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于 ...
- 标准模板库——IO库
IO库设施: . istream(输入流)类型,提供输入操作. . ostream(输出流)类型,提供输出操作. . cin,一个istream对象,从标准输入读取数据. . cout,一个ostre ...
随机推荐
- 百练1041-反反复复-2016正式C题
C:反反复复 总时间限制: 1000ms 内存限制: 65536kB 描述 Mo和Larry发明了一种信息加密方法.他们首先决定好列数,然后将信息(只包含字母)从上往下依次填入各列,并在末尾补充一 ...
- numpy中的复合数组
1.复合数组的创建 # 复合数组,最重要的是定义dtype a = np.array([('ABC', [1, 2, 3])], dtype="U3, 3i4") print(a) ...
- SQLAlchemy中表结构的一对一
1.先导入相对应的库 from flask import Flask from flask_sqlalchemy import SQLAlchemy import pymysql pymysql.in ...
- [LeetCode&Python] Problem 429. N-ary Tree Level Order Traversal
Given an n-ary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- Laravel学习--时间
date("Y-m-d H:i:s"); list($usec, $sec) = explode(" ", microtime()); $time = (flo ...
- SQL经常使用的一些词
sp_helptext: 例:exec sp_helptext proc_name(查看存储过程的定义) sp_rename: 例:exec sp_rename 'proc_name1','proc_ ...
- web四则混合运算2
一.设计思路: 先出题(String型)(上周已经实现),再写方法计算结果,加入控制有无乘除法,范围,参与计算数,出题数,页码显示等简单功能,有无括号和分数的计算目前还没能实现. 二.代码: 界面 & ...
- linux下简单制作iso,img镜像文件
1. 如果你是直接从cd压制iso文件的,执行sudo umount /dev/cdromdd if=/dev/cdrom of=file.iso bs=1024 2. 如果你要把某个文件或者目录压到 ...
- CH5701 开车旅行
题意 5701 开车旅行 0x50「动态规划」例题 描述 小A和小B决定利用假期外出旅行,他们将想去的城市从1到N编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 ...
- Java打印水仙花数
public class Test2 { public static void main(String[] args) { //水仙花 数 指的是一个三位数(100-999) //三位数本身= 百位数 ...