cppPrimer学习17th
cppPrimer学习17th
目录
17.1
17.2
// 17.1 定义一个保存三个 int 值的 tuple,并将其成员分别初始化为10、20和30。
// 17.2 定义一个 tuple,保存一个 string、一个vector 和一个 pair<string, int>。
#include <tuple>
#include <string>
#include <vector>
int main(int argc, const char **argv)
{
std::tuple<int, int, int> a(10, 20, 30);
std::tuple<std::string, std::vector<int>, std::pair<std::string, int>> b("hello", std::vector<int>({1, 2, 3}), std::make_pair<std::string, int>("123", 4));
return 0;
}
17.3
使用类的设计好
使用tuple 写的快
17.9
解释下列每个bitset 对象所包含的位模式:
(a) bitset<64> bitvec(32); 用32 初始化
(b) bitset<32> bv(1010101); 取1010101的低32位
(c) string bstr; cin >> bstr; bitset<8> bv(bstr); 用string的最高8位初始化bitset
17.10
// 17.10使用序列1、2、3、5、8、13、21初始化一个bitset,将这些位置置位。对另一个bitset进行默认初始化,并编写一小段程序将其恰当的位置位
#include <bitset>
#include <vector>
#include <iostream>
using namespace std;
int main(int argc, const char **argv)
{
std::bitset<32> b32;
std::vector<int> v = {1, 2, 3, 8, 13, 21};
for (auto ch : v)
b32.set(ch);
std::cout << b32 << std::endl;
while (1)
;
return 0;
}
17.11
// 17.11 定义一个数据结构,包含一个整型对象,记录一个包含10个问题的真/假测验的解答。如果测验包含100道题,你需要对数据结构做出什么改变(如果需要的话)? 100/8=12.5
#include <bitset>
template <unsigned N>
class quiz
{
public:
quiz(std::string &s) : bset(s) {}
private:
std::bitset<N> bset;
};
int main()
{
std::string s1("0101010101");
std::string s2("0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101");
quiz<10> q1(s1);
quiz<100> q2(s2);
while (1)
;
return 0;
}
17.12
17.13
// 17.13 编写一个整型对象,包含真/假测验的正确答案。使用它来为前两题中的数据结构生成测验成绩。
// 17.12 使用前一题中的数据结构,编写一个函数,它接受一个问题编号和一个表示真/假解答的值,函数根据这两个参数更新测验的解答。//
// 17.11 定义一个数据结构,包含一个整型对象,记录一个包含10个问题的真/假测验的解答。如果测验包含100道题,你需要对数据结构做出什么改变(如果需要的话)? 100/8=12.5
#include <bitset>
#include <iostream>
#include <string>
using namespace std;
template <unsigned N>
class quiz
{
template <unsigned M>
friend ostream &operator<<(ostream &o, const quiz<M> &q);
public:
quiz(const std::string &s) : bset(s) {}
quiz(int s) : bset(s) {}
void set(std::size_t n, bool v) { bset.set(n, v); }
int score(const quiz &correct)
{
return (this->bset ^ correct.bset).flip().count() * 1.0 / N * 100;
}
private:
std::bitset<N> bset;
};
template <unsigned M>
ostream &operator<<(ostream &o, const quiz<M> &q)
{
return o << q.bset << endl;
}
int main()
{
std::string s1("1111100000");
quiz<10> q1(s1);
q1.set(0, 1);
std::cout << q1 << std::endl;
std::cout << q1.score(quiz<10>(10)) << std::endl;
std::cout << q1.score(quiz<10>(string("1111100001"))) << std::endl;
while (1)
;
return 0;
}
17.14
#include <regex>
#include <string>
#include <iostream>
#include <exception>
using namespace std;
int main(int argc, char const *argv[])
{
try
{
//regex reg("[[:alpha:]]*888[[:alpha:]]");
regex reg("[[:alpha:]]*888[[:alpha:]]");
string s = "hello shabi888ok";
smatch ret;
if (regex_search(s, ret, reg))
{
std::cout << "ret= " << ret.str() << std::endl;
}
}
catch (const regex_error &e)
{
std::cout << e.what() << std::endl;
}
try
{
std::regex r1("[[:anum:]]+\\.(cpp|cxx|cc)$", std::regex::icase);
}
catch (std::regex_error e)
{
std::cout << e.what() << "\ncode: " << e.code() << std::endl;
}
try
{
std::regex r1("[[:alnum:]+\\.(cpp|cxx|cc)$", std::regex::icase);
}
catch (std::regex_error e)
{
std::cout << e.what() << "\ncode: " << e.code() << std::endl;
}
try
{
std::regex r1("[[:alnum:]]+\\.cpp|cxx|cc)$", std::regex::icase);
}
catch (std::regex_error e)
{
std::cout << e.what() << "\ncode: " << e.code() << std::endl;
}
while (1)
;
return 0;
}
17.15
// 17.5 编写程序,使用模式查找违反“i在e之前,除非在c之后”规则的单词。
// 你的程序应该提示用户输入一个单词,然后指出此单词是否符号要求。
// 用一些违反和未违反规则的单词测试你的程序。
// 也就是 合法是 i在e之后
//ie 非法
//cie 但是合法
//[^c]ie 非法
//"[[:alpha:]]*[^c]ei[[:alpha:]]*"
//这是一条拼写规则,即通常拼写单词时i在e前,
//除非i前出现了c(这时相反即i在e后):
//如 believe, receive
// 也就是要查找 [^c]ei单词,但是前面不是c的 合法
#include <regex>
#include <string>
#include <iostream>
#include <exception>
using namespace std;
int main(int argc, const char **argv)
{
regex reg;
try
{
//reg.assign("[[:alpha:]]*[^c]ie[[:alpha:]]*"); // 这里没有处理ie开头的
reg.assign("[[:alpha:]]*(cie|[^c]ei)[[:alpha:]]*"); // 这里不去研究正则的内部
//reg.assign("[[:alpha:]]*([^c]ei)[[:alpha:]]*"); // 这里不去研究正则的内部
}
catch (const regex_error &e)
{
std::cout << e.what() << ": " << e.code() << std::endl;
}
string input;
while (std::cout << "pls input" << std::endl, cin >> input)
{
smatch ret;
if (regex_search(input, ret, reg))
{
std::cout << "err" << std::endl;
std::cout << ret.str() << std::endl;
}
else
{
std::cout << "ok" << std::endl;
}
}
return 0;
}
17.16
// 17.17更新你的程序,令它查找输入序列中所有违反"ei"语法规则的单词。
// 17.5 编写程序,使用模式查找违反“i在e之前,除非在c之后”规则的单词。
//这是一条拼写规则,即通常拼写单词时i在e前,
//除非i前出现了c(这时相反即i在e后):
//如 believe, receive
// 也就是要查找 [^c]ei单词,但是前面不是c的 合法
#include <regex>
#include <string>
#include <iostream>
#include <exception>
using namespace std;
int main(int argc, const char **argv)
{
regex reg;
try
{
reg.assign("[[:alpha:]]*(cie|[^c]ei)[[:alpha:]]*"); // 这里不去研究正则的内部
}
catch (const regex_error &e)
{
std::cout << e.what() << ": " << e.code() << std::endl;
}
string input;
while (std::cout << "pls input" << std::endl, getline(cin, input))
{
for (sregex_iterator it(input.begin(), input.end(), reg), end_it;
it != end_it; ++it)
cout << "Err: " << it->str() << endl;
}
return 0;
}
17.18
// 17.18 修改你的程序,忽略包含“ei”但并非拼写错误的单词,如“albeit”和“neighbor”
// 17.17更新你的程序,令它查找输入序列中所有违反"ei"语法规则的单词。
// 17.5 编写程序,使用模式查找违反“i在e之前,除非在c之后”规则的单词。
//这是一条拼写规则,即通常拼写单词时i在e前,
//除非i前出现了c(这时相反即i在e后):
//如 believe, receive
// 也就是要查找 [^c]ei单词,但是前面不是c的 合法
#include <regex>
#include <string>
#include <iostream>
#include <exception>
#include <algorithm>
using namespace std;
int main(int argc, const char **argv)
{
std::vector<std::string> vec{"albeit", "neighbor"};
regex reg;
try
{
reg.assign("[[:alpha:]]*(cie|[^c]ei)[[:alpha:]]*"); // 这里不去研究正则的内部
}
catch (const regex_error &e)
{
std::cout << e.what() << ": " << e.code() << std::endl;
}
string input;
while (std::cout << "pls input" << std::endl, getline(cin, input))
{
for (sregex_iterator it(input.begin(), input.end(), reg), end_it; it != end_it; ++it)
{
if (find(vec.begin(), vec.end(), it->str()) != vec.end())
continue;
cout << "Err: " << it->str() << endl;
}
}
return 0;
}
17.19
为什么可以不先检查m[4]是否匹配了就直接调用m[4].str()?
空字串也可以比较
17.20
// 编写你自己版本的验证电话号码的程序。 抄一下
#include <iostream>
#include <string>
#include <regex>
bool valid(const std::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();
}
//908.555.1500
int main()
{
std::string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})";
std::regex r(phone);
std::smatch m;
std::string s;
while(std::getline(std::cin, s))
{
for(std::sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it)
if(valid(*it))
std::cout << "valid: " << it->str() << std::endl;
else
std::cout << "not valid: " << it->str() << std::endl;
}
return 0;
}
17.28
// 编写函数,每次调用生成并返回一个均匀分布的随机unsigned int。
#include <random>
#include <iostream>
unsigned random_func()
{
static std::default_random_engine e;
static std::uniform_int_distribution<unsigned> u;
return u(e);
}
int main()
{
std::cout << random_func() << std::endl;
return 0;
}
17.29
// 修改上一题中编写的函数,允许用户提供一个种子作为可选参数
#include <random>
#include <iostream>
unsigned random_func()
{
static std::default_random_engine e;
static std::uniform_int_distribution<unsigned> u;
return u(e);
}
unsigned random_func(unsigned i)
{
static std::default_random_engine e(i);
static std::uniform_int_distribution<unsigned> u;
return u(e);
}
int main()
{
std::cout << random_func() << std::endl; //default 1
std::cout << random_func(2) << std::endl;
return 0;
}
17.30
// 再次修改你的程序,此次增加两个参数,表示函数允许返回的最小值和最大值。
#include <random>
#include <iostream>
unsigned random_func()
{
static std::default_random_engine e;
static std::uniform_int_distribution<unsigned> u;
return u(e);
}
unsigned random_func(unsigned i)
{
static std::default_random_engine e(i);
static std::uniform_int_distribution<unsigned> u;
return u(e);
}
unsigned random_func(unsigned i, unsigned min, unsigned max)
{
static std::default_random_engine e(i);
static std::uniform_int_distribution<unsigned> u(min, max);
return u(e);
}
int main()
{
std::cout << random_func() << std::endl; //default 1
std::cout << random_func(2) << std::endl;
for(int i = 0; i < 10; ++i)
std::cout << random_func(1, 0, 10) << std::endl;
return 0;
}
17.31
对于本节中的游戏程序,如果在do循环内定义b和e,会发生什么?
每次随机数一样