【 声明:版权所有,转载请标明出处,请勿用于商业用途。 联系信箱:[email protected]】
17.1 tuple类型
1.tuple是类似pair的模板。每个pair的成员类型都不同,但每个pair都恰好有两个成员。不同tuple类型的成员类型也不相同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的,但一个tuple类型的成员数目可以与另一个tuple类型不同。
要访问一个tuple成员,就要使用一个名为get的标准库函数模板。
2.
tuple支持的操作
tuple<T1,T2,...,Tn> t;
t是一个tuple,成员数位n,第i个成员的类型为Ti。所有成员都进行值初始化
tuple<T1,T2,...,Tn>
t(v1,v2,...,vn);
t是一个tuple,成员类型为T1,T2,...,Tn,每个成员用对应的初始值vi进行初始化。此构造函数是explicit的
make_tuple(v1,v2,...,vn);
返回一个用给定初始值初始化的tuple。tuple的类型从初始值的类型推断
t1
== t2
t1
!= t2
当两个tulpe具有相同数量的成员对应相等时,两个tuple相等。这两个操作使用成员的==运算符来完成。一旦发现某对成员不等,接下来的成员就不用比较了
t1
relop t2
tuple的关系运算使用字典序。两个tuple必须具有相同数量成员。使用<运算符比较t1的成员和t2的对应成员。
get<i>(t)
返回t的第i个成员的引用;如果t是一个左值,结果是一个左值引用;否则,结果是一个右值引用。tuple的所有成员都是public的
tuple_size<tupleType>::value
一个类模板,可以通过一个tuple类型来初始化,它有一个名为value的public
constexpr static数据成员,类型为size_t,表示给定tuple类型中成员的数量
tuple_element<i,tupleType>::type
一个类模板,可以通过一个整型常量和一个tuple类型来初始化,它有一个名为type的public成员,表示给定tuple类型中指定成员的类型。
17.2 bitset类型
1.
初始化bitset的方法
bitset<n> b;
b有n位,每一位均为0,此构造函数是一个constexpr
bitset<n> b(u);
b是unsigned long long值u的低n位的拷贝。如果n大于unsigned
long long的大小,则b中超出unsigned long long的高位被置为0.此构造函数是一个constexpr
bitset<n>
b(s,pos,m,zero,one);
b是string
s从位置pos开始m个字符的拷贝。s只能包含字符zero或one;如果s包含其他任何字符,构造函数会抛出invalid_argument异常。字符在b中分别保存为zero和one。pos默认为0,m默认为string::npos,zero默认为‘0‘,one默认为‘1‘。
bitset<n>
b(cp,pos,m,zero,one);
与上一个构造函数相同,但从cp指向的字符数组中拷贝字符。如果未提供m,则cp必须指向C风格字符串。如果提供了m,则从cp开始必须至少有M个zero或one字符。
2.
bitset操作
b.any()
b中是否存在置位的二进制位
b.all()
b中所有元素都置位了吗
b.none()
b中不存在置位的二进制位吗
b.count()
b中置位的位数
b.size()
一个constexpr函数,返回b的位数
b.text(pos)
若pos位置的位是置位的,则返回true,否则返回false
b.set(pos,v)
b.set()
将位置pos处的位设置为bool值为v。v默认为true。如果未传递实参,则将b中所有位置位
b.reset(pos)
b.reset()
将位置pos处的位复位或将b中所有位复位
b.filp(pos)
b.filp()
改变位置pos处的位的状态或改变b中每一位的状态
b[pos]
访问b中位置pos处的位;如果b是const的,则当该位置位时b[pos]返回一个bool值true,否则返回false
b.to_ulong()
b.to_ullong()
返回一个unsigned
long或一个unsigned long long值,其位模式与相同。如果b中位模式不能放入指定的结果类型,则抛出一个overflow_error异常
b.to_string(zero,one)
返回一个string,表示b中的位模式。zero和one默认值分别为0和1,用来表示b中的0和1
os<<b
将b中二进制位打印为字符1或0,打印到流os
is>>b
从is读取字符存入b。当下一个字符不是1或0时,或是已经读入b.size()个位时,读取过程停止
17.3
正则表达式
1.正则表达式库组件
regex
表示由一个正则表达式的类
regex_match
将一个字符序列与一个正则表达式匹配
regex_search
寻找第一个与正则表达式匹配的子序列
regex_replace
使用给定格式替换一个正则表达式
sregex_iterator
迭代器适配器,调用regex_search来遍历一个string中所有匹配的子串
smatch
容器类,保存在string中搜索的结果
ssub_match
string中匹配的子表达式的结果
17.4 随机数
1.
随机数库的组成
引擎类型:生成随机unsigned整数序列
分布类型:使用引擎返回服从特定概率分布的随机数
2.随机数引擎操作
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
3.分布类型的操作
Dist d;
默认构造函数;使d准备好被使用
其他构造函数依赖于Dist的类型。分布类型的构造函数是explicit的
d(e)
用相同的e连续调用d的话,会根据d的分布式类型生成一个随机数序列;e是一个随机数引擎对象
d.min()
d.max()
返回d(e)能生成的最小值和最大值
d.reset()
重建d的状态,使得随后对d的使用不依赖于d已经生成的值
17.5 IO库再探
1.操作符用于两大类输出控制:控制数值的输出形式以及控制补白的数量和位置。大多数改变格式状态的操纵符都是设置/复原成对的;一个操纵符用来将格式状态设置为一个新值,而另一个用来将其复原,恢复为正常的默认格式。
PS:部分练习答案
练习17.1 & 17.2
#include <iostream> #include <tuple> #include <string> #include <vector> int main() { std::tuple<int,int,int> i3 {10,20,30}; std::tuple<std::string,std::vector<std::string>, std::pair<std::string, int>> t; }
练习17.4
std::vector<matches> findBook(const std::vector<std::vector<Sales_data>>& files, const std::string& book) { std::vector<matches> ret; for (auto it = files.cbegin(); it != files.cend(); ++it) { auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn); if(found.first != found.second) ret.push_back(std::make_tuple(it - files.cbegin(), found.first, found.second)); } return ret; }
练习17.5
std::vector<matches_pair> findBook_pair(const std::vector<std::vector<Sales_data> > &files, const std::string &book) { std::vector<matches_pair> ret; for(auto it = files.cbegin(); it != files.cend(); ++it) { auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn); if(found.first != found.second) ret.push_back(std::make_pair(it - files.cbegin(), std::make_pair(found.first, found.second))); } return ret; }
练习17.6
std::vector<matches_struct> findBook_struct(const std::vector<std::vector<Sales_data> > &files, const std::string &book) { std::vector<matches_struct> ret; for(auto it = files.cbegin(); it != files.cend(); ++it) { auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn); if(found.first != found.second) ret.push_back(matches_struct(it - files.cbegin(), found.first, found.second)); } return ret; }
练习17.10
#include <iostream> #include <bitset> #include <vector> int main() { std::vector<int> v = {1,2,3,5,8,13,21}; std::bitset<32> bset; for (auto i : v) bset.set(i); std::bitset<32> bset2; for (unsigned i = 0; i != 32; ++i) bset2[i] = bset[i]; std::cout <<bset <<std::endl; std::cout <<bset2<<std::endl; }
练习17.11 & 17.12 & 17.13
#ifndef QUIZ #define QUIZ #include <iostream> #include <bitset> #include <utility> #include <string> #include <iostream> //class Quiz template<std::size_t N> class Quiz { public: //constructors Quiz() = default; Quiz(std::string& s) :bitquiz(s) {} //generate grade template<std::size_t M> friend std::size_t grade(Quiz<M> const&, Quiz<M> const&); //print template<std::size_t M> friend std::ostream& operator<<(std::ostream&, Quiz<M> const&); //update bitset void update(std::pair<std::size_t, bool>); private: std::bitset<N> bitquiz; }; #endif template<std::size_t N> void Quiz<N>::update(std::pair<std::size_t, bool> pair) { bitquiz.set(pair.first, pair.second); } template<std::size_t M> std::ostream& operator<<(std::ostream& os, Quiz<M> const& quiz) { os << quiz.bitquiz; return os; } template<std::size_t M> std::size_t grade(Quiz<M> const& corAns, Quiz<M> const& stuAns) { auto result = stuAns.bitquiz ^ corAns.bitquiz; result.flip(); return result.count(); } int main() { //Ex17_11 std::string s = "1010101"; Quiz<10> quiz(s); std::cout << quiz << std::endl; //EX17_12 quiz.update(std::make_pair(1, true)); std::cout << quiz << std::endl; //Ex17_13 std::string answer = "10011"; std::string stu_answer = "11001"; Quiz<5> ans(answer), stu_ans(stu_answer); std::cout << grade(ans, stu_ans) << std::endl; return 0; }
练习17.14 & 17.15 & 17.16
#include <iostream> using std::cout; using std::cin; using std::endl; #include<string> using std::string; #include <regex> using std::regex; using std::regex_error; int main() { //! for ex17.14 //! error_brack try { regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase); } catch(regex_error e) { cout << e.what() << " code: " << e.code() << endl; } //! for ex17.15 regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", regex::icase); string s; cout << "Please input a word! Input 'q' to quit!" << endl; while(cin >> s && s != "q") { if(std::regex_match(s, r)) cout << "Input word " << s << " is okay!" << endl; else cout << "Input word " << s << " is not okay!" <<endl; cout << "Please input a word! Input 'q' to quit!" << endl; } cout << endl; //! for ex17.16 r.assign("[^c]ei", regex::icase); cout << "Please input a word! Input 'q' to quit!" << endl; while(cin >> s && s != "q") { if(std::regex_match(s, r)) cout << "Input word " << s << " is okay!" << endl; else cout << "Input word " << s << " is not okay!" <<endl; cout << "Please input a word! Input 'q' to quit!" << endl; } return 0; }
练习17.17
& 17.18
#include <iostream> using std::cout; using std::cin; using std::endl; #include<string> using std::string; #include <regex> using std::regex; using std::sregex_iterator; int main() { string s; cout << "Please input a sequence of words:" << endl; getline(cin, s); cout << endl; cout << "Word(s) that violiate the \"ei\" grammar rule:" << endl; string pattern("[^c]ei"); pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*"; regex r(pattern, regex::icase); for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it) cout << it->str() << endl; return 0; }
练习17.19 & 19.20
#include <iostream> #include<string> #include <regex> using std::cout; using std::cin; using std::endl; using std::string; using std::regex; using std::sregex_iterator; using std::smatch; bool valid(const smatch& m); int main() { string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})"; regex r(phone); smatch m; string s; bool valid_record; while (getline(cin, s)) { valid_record = false; for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it) { valid_record = true; if (valid(*it)) cout << "valid phone number: " << it->str() << endl; else cout << "invalid phone number: " << it->str() << endl; } if (!valid_record) cout << "invalid record!" << endl; } return 0; } bool valid(const smatch& m) { if (m[1].matched) return m[3].matched && (m[4].matched == 0 || m[4].str() == " "); else return !m[3].matched && m[4].str() == m[6].str(); }
练习17.28 & 17.29 & 17.30
#include <iostream> #include <random> //ex17.28 unsigned random_gen() { static std::default_random_engine e; static std::uniform_int_distribution<unsigned> ud; return ud(e); } //ex17.29 unsigned random_gen(unsigned seed) { static std::default_random_engine e(seed); static std::uniform_int_distribution<unsigned> ud; return ud(e); } //ex17.30 unsigned random_gen(unsigned seed, unsigned min, unsigned max) { static std::default_random_engine e(seed); static std::uniform_int_distribution<unsigned> ud(min,max); return ud(e); } int main() { std::string temp; while(std::cin >> temp) std::cout << std::hex << random_gen(19,1,10) << std::endl; return 0; }
版权声明:本文为博主原创文章,如果转载,请注明出处