【 声明:版权所有,转载请标明出处,请勿用于商业用途。 联系信箱:[email protected]】
17.1 tuple类型
1.tuple是类似pair的模板。每个pair的成员类型都不同,但每个pair都恰好有两个成员。不同tuple类型的成员类型也不相同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的,但一个tuple类型的成员数目可以与另一个tuple类型不同。
要访问一个tuple成员,就要使用一个名为get的标准库函数模板。
2.
tuple支持的操作
tuple
t是一个tuple,成员数位n,第i个成员的类型为Ti。所有成员都进行值初始化
tuple
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(t)
返回t的第i个成员的引用;如果t是一个左值,结果是一个左值引用;否则,结果是一个右值引用。tuple的所有成员都是public的
tuple_size
一个类模板,可以通过一个tuple类型来初始化,它有一个名为value的public constexpr static数据成员,类型为size_t,表示给定tuple类型中成员的数量
tuple_element::type
一个类模板,可以通过一个整型常量和一个tuple类型来初始化,它有一个名为type的public成员,表示给定tuple类型中指定成员的类型。
17.2 bitset类型
1.
初始化bitset的方法
bitset
b有n位,每一位均为0,此构造函数是一个constexpr
bitset
b是unsigned long long值u的低n位的拷贝。如果n大于unsigned long long的大小,则b中超出unsigned long long的高位被置为0.此构造函数是一个constexpr
bitset
b是string s从位置pos开始m个字符的拷贝。s只能包含字符zero或one;如果s包含其他任何字符,构造函数会抛出invalid_argument异常。字符在b中分别保存为zero和one。pos默认为0,m默认为string::npos,zero默认为'0',one默认为'1'。
bitset
与上一个构造函数相同,但从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中二进制位打印为字符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
#include
#include
#include
int main()
{
std::tuple i3 {10,20,30};
std::tuple, std::pair> t;
}
std::vector
findBook(const std::vector>& files, const std::string& book)
{
std::vector 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;
}
std::vector findBook_pair(const std::vector > &files, const std::string &book)
{
std::vector 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;
}
std::vector findBook_struct(const std::vector > &files, const std::string &book)
{
std::vector 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;
}
#include
#include
#include
int main()
{
std::vector 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 <
#ifndef QUIZ
#define QUIZ
#include
#include
#include
#include
#include
//class Quiz
template
class Quiz
{
public:
//constructors
Quiz() = default;
Quiz(std::string& s) :bitquiz(s) {}
//generate grade
template
friend std::size_t grade(Quiz const&, Quiz const&);
//print
template
friend std::ostream& operator<<(std::ostream&, Quiz const&);
//update bitset
void update(std::pair);
private:
std::bitset bitquiz;
};
#endif
template
void Quiz::update(std::pair pair)
{
bitquiz.set(pair.first, pair.second);
}
template
std::ostream& operator<<(std::ostream& os, Quiz const& quiz)
{
os << quiz.bitquiz;
return os;
}
template
std::size_t grade(Quiz const& corAns, Quiz 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
using std::cout;
using std::cin;
using std::endl;
#include
using std::string;
#include
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!" <> s && s != "q")
{
if(std::regex_match(s, r))
cout << "Input word " << s << " is okay!" << endl;
else
cout << "Input word " << s << " is not okay!" <
练习17.17 & 17.18
#include
using std::cout;
using std::cin;
using std::endl;
#include
using std::string;
#include
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;
}
#include
#include
#include
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();
}
#include
#include
//ex17.28
unsigned random_gen()
{
static std::default_random_engine e;
static std::uniform_int_distribution ud;
return ud(e);
}
//ex17.29
unsigned random_gen(unsigned seed)
{
static std::default_random_engine e(seed);
static std::uniform_int_distribution 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 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;
}