part1.tuple类型
1.一个tuple可以有任意数量的成员。每个确定tuple类型的成员数目是固定的。是一个快速而随意的数据结构。
2.构造函数是explicit,必须使用直接初始化:
tuple< size_t, size_t, size_t > threeD{1, 2, 3};
3.make tuple使用初始值的类型来推断tuple类型。
auto item = make_tuple( “0-999-xxx”,3, 20.00);
4.使用get访问成员
auto book = get<0>(item);//第一个元素
5.tuple的类型信息
typedef decltype(item) trans;
size_t sz = tuple_size<trans>:: value;//元素数量
tuple_element<1, trans >::type cnt = get<1>(item);//cnt表示得到的类型
6.常见用途是从一个函数返回多个值
vector<matches> ret;
ret.push_back(make_tuple(xxx,xxx,xxx) );
return ret;
part2.bitset类型
1.初始化
bitset<32> bitvec(1U);//32位,低位为1
2.用unsigned 值初始化bitset,如果bitset大小大于一个unsigned long long 中的二进制位数,则剩余高位被置零。
否则,只使用给定值的低位,超出bitset部分被丢弃。
3.也可以从string初始化bitset。此时字符串中最小的字符对应高位。
4.常用函数
any(),all(),none(),count().都是针对是否有1而言的。不接受参数,对整个集合执行给定操作。
set(pos,v),reset(pos),flip(pos).接受一个位置参数的版本则对指定位执行操作。
to_string(zero, one);
5.如果bitset中的值不能放入给定类型中(bitset太小了),会有异常。
to_ulong()
to_ullong()
part3.正则表达式
1.regex类表示一个正则表达式。
2.regex_match,regex_search确定一个给定字符序列与一个给定regex是否匹配。
如果整个输入序列与表达式匹配,则regex_match函数返回true。
如果输入序列中的一个子串与表达式匹配,则regex_search函数返回true。
3.用法:
string pattern(“ [^c]ei ”);
pattern = “[ [ :alpha: ] ]* ” + pattern + “[ [ :alpha: ] ]*”; //“[ [ :alpha: ] ]*”;表示零个或多个字母。
regex r(pattern, regex::icase);//忽略大小写
smatch results;
string test_str = “xxx xxx xxx”;
for(sregex_iterator it(test_str.begin(), test_str.end(), r ), end_it;
it != end_it; ++it ) { //
end_it是一个空sregex_iterator,起到尾后迭代器的作用
cout << it->str() << endl;//输出所有匹配,而非只是第一个
//还可以输出匹配位置的上下文:前缀以及后缀
auto pos = it->prefix().length(); //suffix是后缀
pos = pos > 40 ? pos - 40 : 0;
cout << it->prefix().str().substr(pos );
}
4.默认使用ECMAScript规范。还有其他的比如awk, grep等
5.正则表达式的语法是在运行时解析的。编译过程很慢,所以不建议放入循环中多次创建。
6.正则表达式库类
string regex,smatch,sregex_iterator
const char* regex, cmatch, cregex_iterator
7.使用子表达式
1)正则表达式语言特性
\{d}{3}匹配三个数字的序列
[-.]方括号表示匹配这些字符中的任意一个。点在括号里没有特殊含义
?表示组件是可选的。
\是特殊字符,括号( 也是特殊字符。因此用\(表示括号使我们模式的一部分而不是特殊字符。用\\表示需要的是反斜线而不是特殊符号。
2)多个表达式:匹配电话号码 908.555.1800
(\\()? 表示区号部分
可选的左括号
(\\d{3})表示区号
(\\))?可选的右括号
([-. ])?可选的分隔符
对于七个字表达式的pattern,每个smatch对象会包含八个ssub_match,[0]表示整个匹配。[1]…[7]表示对应的表达式。
即使有一个完整的匹配了,我们还是不知道每个可选的子表达式是否是匹配的一部分。如果是的话,则其对应的ssub_match对象的matched成员为true。
判断括号匹配可以用:
bool valid(const smatch& m)
{
if(m[1].matched) &&m[3].matched
//then
}
调用时:
for(sregex_iterator it(test_str.begin(), test_str.end(), r ), end_it;
it != end_it; ++it )
if(valid (*it) ){ ….} //*it 就是smatch类型
8.使用regex_replace
//在替换的字符串中使用第二个,第五个和第七个子表达式,其余的忽略。
string fmt = “$2.$5.$7”;
regex r(phone);
string number = “(908) 555-1800”;
cout << regex_replace(number, r, fmt ) << endl; //output: 908.555.1800,被格式化
cout << regex_replace(number, r, fmt, format_no_copy ) << endl; //只拷贝它替换的文本,不输出未匹配的部分
part4.随机数
1.随机数库组成: 引擎,生成随机的unsigned整数序列
分布,使用引擎
返回服从特定概率分布的随机数
2.用法:
default_random_engine e;
while(1)
cout<< e() << endl; //随机数引擎的输出不能直接用,因为值的范围与我们要求的不符,需要正确转换范围
3.所以应该是:
uniform_int_distribution< unsigned> u(0, 9);//生成0到9之间的均匀分布随机数
default_random_engine e;
while(1)
cout<< u(e) << endl;//不是u(e() ),我们传递的是引擎本身,而不是它的下一个值。
4.因此,随机数发生器是指分布对象和引擎对象的组合。
5.编写生成的函数应该这样:
vector<unsigned> goog_randVec(){
static default_random_engine e; //不加static,则每次生成的100个随机数都是一样的。
staic uniform_int_distribution<unsigned> u(0, 9); //因此序列一样有利于调试,但一旦正式使用,需要不一样
vector<unsigned> ret;
for(;i<100;)
ret.push_back( u(e) );
return ret;
}
6.可以使用时间种子
default_random_engine e1(time(0));//适用于生成种子的间隔为秒级或更长的应用。
7.生成随机浮点数
default_random_engine e;
uniform_real_distribution<double> u(0, 1);
//或使用分布模板的默认结果类型,为double
uniform_real_distribution<> u(0, 1);
8.其他分布
normal_distribution <> n(4, 1.5);//mean = 4, var = 1.5
bernoulli_distribution b;//默认是50/50
bernoulli_distribution b(0.55);//55/45
part5.IO库再探
1.当操纵符改变流的状态时,通常改变后的状态对后续都生效,因此不用的时候需要恢复为默认。
2.作用:
1)可以按进制打印,加上进制信息:0x
2)指定打印精度
cout.setprecision(12);
3)打印小数点
cout << showpoint << 10.0 << noshowpoint << endl;
4)输出补白:
setfill()
left,right, setw
cout << setfill(‘#’)
<<“i = “ << setw(12) << i << ‘\n’ ;//以’\n’为单位进行左右对齐,以及字符站位,填充。
<<setfill(‘ ‘ );//恢复到正常补白字符
3.未格式化的输入输出
char ch;
while (cin.get(ch))
cout.put(ch);
使用peek,unget,putback,可以退回最多一个值。返回类型是int,而非char,为了存储更多信息,可以返回文件尾标记。
4.流随机访问
iostream 不支持。只适用于fstream和sstream
seek,tell。
fstream inOut(“”,fsteram::ate);
auto end_mark = inOut.tellg();
inOut.seekg(0, fstream::beg);