C++primer17章答案(第五版)
17.1
17.2
#include <iostream>
#include<vector>
#include<tuple>
int main()
{
std::tuple<int, int, int> t1{ 10,20,30 };
std::tuple<std::string, std::vector<std::string>, std::pair<std::string, int>>t2{ "hello",{"1","2","3"},{"string",1} };
}
17.3
原版程序设计更加正式,方便重构。而使用tuple更快捷,方便调试。
17.4
typedef tuple<vector<Sales_data>::size_type, vector<Sales_data>::const_iterator, vector<Sales_data>::const_iterator> matches;
vector<matches> findBook(const vector<vector<Sales_data>>& files, const string& s)
{
vector<matches>ret;
for (auto it=files.cbegin();it!=files.cend();++it)
{
auto found = equal_range(it->cbegin(), it->cend(), s,compareIsbn);
if (found.first != found.second)
ret.push_back({ it - files.cbegin(),found.first,found.second });
}
return ret;
}
17.5
typedef pair<vector<Sales_data>::size_type, pair< vector<Sales_data>::const_iterator, vector<Sales_data>::const_iterator>> matches_pair;
vector<matches_pair> findBook_pair(const vector<vector<Sales_data>>& files, const string& s)
{
vector<matches_pair>ret;
for (auto it = files.cbegin(); it != files.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(),s,compareIsbn);
if (found.first != found.second)
ret.push_back(make_pair( it - files.cbegin(),make_pair(found.first,found.second)) );
}
return ret;
}
17.6
struct matches_struct
{
matches_struct(vector<Sales_data>::size_type s, vector<Sales_data>::const_iterator b, vector<Sales_data>::const_iterator e)
:sz(s), beg(b), end(e) {}
vector<Sales_data>::size_type sz;
vector<Sales_data>::const_iterator beg;
vector<Sales_data>::const_iterator end;
};
vector<matches_struct> findBook_struct(const vector<vector<Sales_data>>& files, const string& s)
{
vector<matches_struct>ret;
for (auto it = files.cbegin(); it != files.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(), s, compareIsbn);
if (found.first != found.second)
ret.push_back(matches_struct(it - files.cbegin(),found.first,found.second));
}
return ret;
}
17.7
tuple版本更好,更加灵活。
17.8
将会默认初始化一个对象
17.9
- 0000000000000000000000000000000000000000000000000000000000100000
- 00000000000011110110100110110101
- 取决于你输入的字符串
17.10
#include <iostream>
#include<vector>
#include<bitset>
int main()
{
std::vector<int>ivec{ 1,2,3,5,8,13,21 };
std::bitset<32>bits1;
for (auto i : ivec)
bits1.set(i);
std::bitset<32>bits2;
for (unsigned int i = 0; i < 32; i++)
{
bits2[i] = bits1[i];
}
}
17.11
17.12
17.13
#include <iostream>
#include<bitset>
template<unsigned N>
struct Quiz
{
template<std::size_t M>
friend std::ostream& operator<<(std::ostream& os,const Quiz<M>&);
Quiz() = default;
Quiz(const std::string& s) :bitquiz(s) {}
void update(std::pair<unsigned, bool>);
int grade(const Quiz& correct);
private:
std::bitset<N>bitquiz;
};
template<unsigned N>
void Quiz<N>::update(std::pair<unsigned, bool>p)
{
bitquiz.set(p.first, p.second);
}
template<unsigned N>
int Quiz<N>::grade(const Quiz& correct)
{
auto grade = bitquiz ^ correct.bitquiz;
grade.flip();
return grade.count();
}
template<std::size_t M>
std::ostream& operator<<(std::ostream& os, const Quiz<M>&q)
{
os << q.bitquiz << std::endl;
return os;
}
int main()
{
std::string s1("1111100000");
Quiz<10> q1(s1);
q1.update({ 0, 1 });
std::cout << q1 << std::endl;
std::cout << q1.grade(Quiz<10>(std::string("1111100001"))) << std::endl;
}
17.14
try {
regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
}
catch (regex_error e)
{
cout << e.what() << " code: " << e.code() << endl;
}
try
{
regex r1("[[:anum:]]+\\.(cpp|cxx|cc)$", regex::icase);
}
catch (std::regex_error e)
{
cout << e.what() << "code: " << e.code() << endl;
}
17.15
regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", regex::icase);
string s;
cout << "Please input a word! Input 'q' to quit!" << endl;
std::smatch results;
while (cin >> s && s != "q")
{
if (std::regex_match(s,results, r))
cout << "Input word " << results.str() << " is error!" << endl;
else
cout << "Input word " << s << " is okay!" << endl;
cout << "Please input a word! Input 'q' to quit!" << endl;
}
17.16
只有[^c]ei初始化,只能匹配到字符串长度为3的非c开头的字符串ei
17.17
17.18
#include <iostream>
#include<regex>
#include<vector>
using namespace std;
int main()
{
regex pattern("[[:alpha:]]*[^c]ei[[:alpha:]]*",regex::icase);
string s;
cout << "Please input a sequence of words:" << endl;
getline(cin, s);
cout << endl;
vector<string>svec{ "albeit","neighbor" };
for (sregex_iterator it(s.cbegin(), s.cend(), pattern), end_it; it != end_it; it++)
{
if (find(svec.cbegin(), svec.cend(), it->str()) != svec.end())
continue;
cout << it->str() << " ";
}
}
17.19
因为空字符串也可以比较
17.20
#include <iostream>
#include <regex>
using namespace std;
bool vaild(const smatch& m)
{
if (m[1].matched)
return m[3].matched && (m[4].matched == false || m[4].str() == " ");
else
return !m[3].matched && m[4].str() == m[6].str();
}
int main()
{
string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
regex r(phone);
string s;
smatch m;
while (getline(cin, s))
{
for (sregex_iterator it(s.cbegin(), s.cend(), r), end_it; it != end_it; it++)
{
if (vaild(*it))
cout << "Valid: " << it->str() << endl;
else
cout << "Not vaild: " << it->str() << endl;
}
}
}
17.21
#include <iostream>
#include<fstream>
#include <regex>
#include<vector>
#include<sstream>
using namespace std;
struct PersonInfo
{
string name;
vector<string>phones;
};
bool read_record(istream& is, vector<PersonInfo>& people)
{
if (is)
{
string line, phone;
while (getline(is, line))
{
PersonInfo info;
istringstream record(line);
record >> info.name;
while (record >> phone)
{
info.phones.push_back(phone);
}
people.push_back(info);
}
return true;
}
else
return false;
}
bool valid(const smatch& m)
{
if (m[1].matched)
return m[3].matched && (m[4].matched == false || m[4].str() == " ");
else
return !m[3].matched && m[4].str() == m[6].str();
}
int main()
{
string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
regex r(phone);
vector<PersonInfo>people;
ifstream ifs("C:\\Users\\Kaji\\Desktop\\PeopleInfo.txt");
if (read_record(ifs, people))//读取文件中的信息,传入到vector中
{
smatch result;
for (auto person : people)//两层循环,对每个人的所有电话号码甄别,并分别输出错误与正确的电话号码
{
ostringstream formatted, badNums;
for (auto it=person.phones.begin();it!=person.phones.end();it++)
{
if (regex_match(*it, result, r) && valid(result))
formatted << *it << " ";
else
badNums << *it << " ";
}
if (!formatted.str().empty())
cout << person.name << " " << formatted.str() << endl;
if (!badNums.str().empty())
cout << person.name << " invalid number(s) " << badNums.str() << endl;
}
}
}
17.22
“(\()?(\d{3})(\))?([[:blank:]])?(\d{3})([[:blank:]])?(\d{4})”
17.23
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
#include <regex>
using std::regex;
using std::smatch;
using std::sregex_iterator;
bool valid(const std::smatch& m)
{
if (m[2].matched && !m[3].matched)
return false;
else
return true;
}
int main()
{
string code = "(\\d{5})([-])?(\\d{4})?";
regex r(code);
string line;
smatch m;
while (cin>>line)
{
if(std::regex_search(line,m,r))
{
if (valid(m))
cout << "Valid postal code: " << m.str() << endl;
else
cout << "Invalid postal code: " << m.str() << endl;
}
}
return 0;
}
17.24
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main()
{
string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string format = "$2.$5.$7";
regex r(pattern);
string s;
while (getline(cin, s))
{
cout << regex_replace(s, r, format) << endl;
}
return 0;
}
17.25
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main()
{
string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string fmt = "$2.$5.$7.";
regex r(pattern);
string s;
while (getline(cin, s))
{
smatch result;
regex_search(s, result, r);
if (!result.empty())
{
cout << result.format(fmt) << endl;
}
else
{
cout << "No match" << endl;
}
}
return 0;
}
17.26
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main()
{
string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string fmt = "$2.$5.$7.";
regex r(pattern);
string s;
smatch result;
while (getline(cin, s))
{
sregex_iterator test(s.cbegin(), s.cend(),r),end_it;
if (test == end_it)
{
cout << "No match" << endl;
}
else if (++test != end_it)
{
sregex_iterator it(s.cbegin(), s.cend(), r);
it++;
for (; it != end_it; it++)
{
cout << it->format(fmt) << " ";
}
}
else
{
for (sregex_iterator it(s.cbegin(), s.cend(), r); it != end_it; it++)
{
cout << it->format(fmt) << " ";
}
}
cout << endl;
}
return 0;
}
17.27
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
#include <regex>
using std::regex;
using std::smatch;
using std::sregex_iterator;
bool valid(const smatch& m)
{
if (m[2].matched && !m[3].matched)
return false;
else
return true;
}
int main()
{
string code = "(\\d{5})([-. ])?(\\d{4})?";
regex r(code);
string line;
smatch m;
string fmt = "$1-$3";
while (cin>>line)
{
if (std::regex_search(line, m, r))
{
if (valid(m)&& m[3].matched)
cout << "Valid postal code: " << m.format(fmt) << endl;
else if(valid(m))
cout << "Valid postal code: " << m.str()<< endl;
else
cout << "Invalid postal code: " << m.str() << endl;
}
else
cout << "NO match " << endl;
}
return 0;
}
17.31
每次循环都会产生同样的值
17.32
未定义的标识符
17.33
来源
include <iostream>
using std::cout;
using std::endl;
#include <fstream>
using std::ifstream;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <random>
using std::default_random_engine;
using std::uniform_int_distribution;
#include <ctime>
using std::time;
#include <algorithm>
using std::sort;
using std::find_if;
#include <utility>
using std::pair;
int main() {
typedef pair<string, string> ps;
ifstream i("d.txt");
vector<ps> dict;
string str1, str2;
// read wirds from dictionary
while (i >> str1 >> str2) {
dict.emplace_back(str1, str2);
}
i.close();
// sort words in vector
sort(dict.begin(), dict.end(), [](const ps &_ps1, const ps &_ps2){ return _ps1.first < _ps2.first; });
i.open("i.txt");
default_random_engine e(unsigned int(time(0)));
// read words from text
while (i >> str1) {
// find word in dictionary
vector<ps>::const_iterator it = find_if(dict.cbegin(), dict.cend(),
[&str1](const ps &_ps){ return _ps.first == str1; });
// if word doesn't exist in dictionary
if (it == dict.cend()) {
// write it itself
cout << str1 << ' ';
}
else {
// get random meaning of word
uniform_int_distribution<unsigned> u (0, find_if(dict.cbegin(), dict.cend(),
[&str1](const ps &_ps){ return _ps.first > str1; }) - it - 1);
// write random meaning
cout << (it + u(e))->second << ' ';
}
}
return 0;
}
17.34
略
17.35
#include <iostream>
using namespace std;
int main()
{
cout <<uppercase<< "defalut format: "<<hexfloat << 100 * sqrt(2.0) << endl;
cout << "scientific: : " << scientific << 100 * sqrt(2.0) << endl;
}
17.36
int main()
{
cout <<"default format: " << 100 * sqrt(2.0) << '\n'
<< "scientific: " << scientific << 100 * sqrt(2.0) << '\n'
<< "fixed decimal: " << fixed << 100 * sqrt(2.0) << '\n'
<< "hexidecimal: " << uppercase << hexfloat << 100 * sqrt(2.0) << '\n'
<< "use defaults: " << defaultfloat << 100 * sqrt(2.0)
<< "\n\n";
}
17.37
int main()
{
cout <<left<<setw(15) << "default format:" <<setw(25)<< right<< 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "scientific:" << scientific << setw(25) << right << 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "fixed decimal:" << setw(25) << fixed << right << 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "hexidecimal:" << setw(25) << uppercase << hexfloat << right << 100 * sqrt(2.0) << '\n'
<< left << setw(15) << "use defaults:" << setw(25) << defaultfloat << right << 100 * sqrt(2.0)
<< "\n\n";
}
17.37
空行不影响输入,长度超过字符数组大小的行会损坏堆栈
#include <iostream>
#include<fstream>
using namespace std;
int main()
{
char a[40];
ifstream ifs("C:\\Users\\Kaji\\Desktop\\test.txt");
while (ifs)
{
ifs.getline(a, 40);
cout << a << endl;
}
}
17.38
#include <iostream>
#include<fstream>
using namespace std;
int main()
{
char a[40];
ifstream ifs("C:\\Users\\Kaji\\Desktop\\test.txt");
while (ifs)
{
ifs.getline(a, 40);
int size = ifs.gcount();
cout.write(a, size);
cout << endl;
}
}
17.39
#include <iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
fstream file("C:\\Users\\Kaji\\Desktop\\test.txt", fstream::in | fstream::out | fstream::ate);
auto end_mark = file.tellg();
file.seekg(0,fstream::beg);
string line;
size_t size = 0;
while (file && file.tellg() != end_mark&&getline(file,line))
{
size += line.size()+1;
auto mark = file.tellg();
file.seekg(0,fstream::end);
file << size;
if (mark != end_mark)
file << " ";
file.seekg(mark);
}
file.seekg(0,fstream::end);
file << '\n';
file.seekg(0,fstream::beg);
while (getline(file, line))
{
cout << line << endl;
}
return 0;
}