美文网首页
Chapter 17 Special STL 标准库特殊设施

Chapter 17 Special STL 标准库特殊设施

作者: 再凌 | 来源:发表于2020-12-21 23:09 被阅读0次

tuple

一个快速而随意的数据结构

操作 含义
tuple<T1, T2, T3>t(v1, v2, v3) 初始化t
make_tuple(v1, v2 v3) 用给定的值来类型推断
get<i>(t) 返回对第i个成员的引用
tuple_size<tupleType>::vaue 对于给定的tupleType. 能够得到成员的数量
tuple_element<i, tupleType>::type 能够得到某一个tuple中某一个成员的类型

bitset

bitset<size> name(value), 其中size必须是常量, 初始值value是uLL类型
如:
bitset<32> bitvec(1)初始化32位的大小, 初始值为1

构造方法还有
bitset<n> b(s, pos, m, zero, one), 字符串s从pos开始的m位, 其中只能含有zero和one, 否则抛出异常, 注意: string中位置后的会放在bitset的[0]位
bitset<n> b(arr, pos, m, zero, one), 从字符数组arr中构造

bitset的操作

any, all, none, count, size, test, set(pos), reset(pos), flip(pos)翻转, b[pos], b.to_ulong(), os<<b, is >> b读取满或者不是01的字符

Regex

初始化可以用string , 一对表示字符范围的迭代器, C类型的string, 字符指针和计数器, 花括号表示的字符们

查找有两个主要的函数:

  • regex_search() string不必完全匹配regex, string的子串匹配即可
  • regex_match() string完全匹配regex才会返回true

参数可以是两种:

  1. (seeq, m, r, mft)
  2. (seeq, r, mft)

其中:
seeq是字符序列
m是是match对象, 用来保存匹配结果的细节(m的类型必须和seeq完全相同)
r是Regex对象
mtf是option值, 只能选后面其中一种特性且必选, 默认为ECMAScript. (支持六种Regex语法), 大小写问题icase, 保存否匹配的子表达式nosubs, 执行速度优化optimize

include<regex>
string pattern("[^c]ei"); // 查找ei前面没有c的串
pattern = "[[::alpha]]*" +  pattern + "[[::alpha::]]*"; //[[::alpha::]]代表任意字母
regex r(pattern);
smatch results;

string test_str("receipt friend theif receive");

if(regex_search(test_str, results, r))//匹配了freind 和thief, 但是regex_search只会找一个, 因此打印freind
  cout << reesults.str() <<endl;

正则表达式是在运行的时候被编译的(因此尽量不要在循环内创建), 因此只有运行的时候通过regex_error来知道异常

try{
  }cache(regex_error e)
    {cout << e.what() << e.code();}

可以像C++一样得到编译的提示, code可以找到对应的错误码


regex迭代器

regex的搜索只能返回一个, 引入迭代器, 使得对于输入序列, 迭代器会返回所有的匹配结果
这个迭代器的类型就是sregex_iterater(stringBegin, stringEnd, r), 入股sregex_iterater没有那些参数, 创建的就是尾后迭代器.

itr-> 是smatch对象, itr->str(), 得到string

smatch高级用法

smatch 有prefix 和suffix成员, 指向了前, 后的ssub_match., ssub_match有str成员和length成员, 能够让用户打印出来匹配的string的前面和后面的那个常规string

子匹配

对于一个smatch匹配, 打印results.str(n)的时候可以打印子匹配(子皮配就是普通括号构成的), 打印出这个结果中匹配第n个部分的内容

这个特性可以用于特别复杂的正则表达式, 分步骤进行判断

替换操作

regex_replace(source_string, regex, fmt, option);//option是可选的
其中fmt是要进行的替换. 默认情况是replace会输出整个输出序列, 不匹配的部分会原样输出.
string fmt = "2.5.$7";

意味着要用第二个第五个和第七个子皮配来组成新的smatch, 结果通过regex_replace的返回值得到

option取值:


image.png

随机数

使用系统库提供的crand有几个问题:

  • 是均匀随机的
  • 产生的数不好进行规范化

使用C++11提供的引擎来生成一个随机数, 使用分布来将引擎生成的随机数服从特定的概率分布化

default_random_engine e;

e是一个能够生成随机数的函数对象, 每一次调用都可以生成一个随机数(cout << e() << endl;), 但是注意, 他生成数的序列永远是相同的, 所以定义如果放在循环内, 那么每次得到的数都是一样的.

相关的操作还有

e.seed(s) // 使用s作为种子
e.min()
e.max()
e.discard(u) //将引擎e推进u步, u为unsigned long long

引擎生成数之后交给分布, 来得到希望的分布范围内的随机数.
uniform_int_distribution<unsigned> u(0,9); // 生成的是unsigned类型的随机数, 可以是任意浮点或者整形
cout << u(e) << endl;

注意传入给u的是整个e对象, 因为有可能u要利用e操作好几次才能得到目的值

其他的分布类型还有default_real_distributtion<double>生成无符号的随机实数(传统的crand实现根本不能做到无理数也能等概率的参加随机). 正态分布normal_distribution<>, 伯努利分布bernoulli_distribution, 生成值得含义是伯努利分布返回true的概率, 默认是0.5, 初始化提供一个固定的浮点数, 可以更改生成true的概率, 如bernoulli_distribution b(0.55) , 那么生成true的概率为55/45

总之记住: 引擎和分布都要在循环外定义, 或者在函数中被定义成static类型.

IO库

格式化IO状态

通过设置/反设置状态, 可以改变IO流的格式, 如

cout << boolalpha << isRunning << endl; // 使用Ture/ False来打印而不是0/1
cout <<noboolalpha // 恢复

cout << hex <<20;
cout <<showbase; //展示0x
cout << noshowbase

类似的还有skipws(输入缓冲区跳过空白符) ends(插入空字符 然后刷新ostream缓冲区)

.get()方法是得到一个未处理的字节, put()同理, 读取并不忽略任何空白符

回退

.peek()方法能够读出下一个字符, 但是不从流中删除
.unget()能退回上一个被读出的字符, 但这个方法只能用一次
.putback()方法需要提供一个值, 保证退回的值和这个值一致

上述方法返回的是int类型, 因为可以返回EOF

多字节操作

in.get(buffer, len, delim) 写入到buffer地址, 总长度为len, 并且如果有delim字符直接停止读取, delim不取走

in.getline(sink, size, delim) 同上, 但是读出并丢弃delim

in.gcount() 返回上一次未格式化IO从is总读出的字节数

os.write(source, size) 把source地址, size长的字节写入os

in.ignore(size, delim), 忽略包括delim的总共size个字符

相关文章

网友评论

      本文标题:Chapter 17 Special STL 标准库特殊设施

      本文链接:https://www.haomeiwen.com/subject/fjkquktx.html