练习17.1
int main(void) { std::tuple<int, int, int> nums(10, 20, 30); return 0; }
练习17.2
std::tuple<string, vector<string>, std::pair<string, int>> duo;
练习17.3
class TextQuery { friend class QueryResult; public: TextQuery() :text(new StrVec, DebugDelete("TextQuery::StrVec")), query_words(new map<string, std::shared_ptr<set<size_t>>>, DebugDelete("TextQuery::map<string, std::shared_ptr<set<size_t>>>")) {} TextQuery(ifstream& ifs); std::tuple<string, std::shared_ptr<set<size_t>>, std::shared_ptr<StrVec>> query(string s) const; ~TextQuery(); private: std::shared_ptr <StrVec> text; std::shared_ptr<map<string, std::shared_ptr<set<size_t>>>> query_words; }; class QueryResult { public: friend std::ostream& print(std::ostream& os, const QueryResult qr); using QueryIterator = set<size_t>::iterator; public: QueryResult(string& w, std::shared_ptr<set<size_t>> n, std::shared_ptr<StrVec> i) :word(w), nos(new set<size_t>, DebugDelete("QueryResult::set<size_t>")), inputs(new StrVec, DebugDelete("QueryResult::StrVec")) { nos = n; inputs = i; } ~QueryResult(); QueryIterator begin() { return nos->begin(); } QueryIterator end() { return nos->end(); } std::shared_ptr <StrVec> get_file() { return inputs; } private: string word; std::shared_ptr<set<size_t>> nos; std::shared_ptr<StrVec> inputs; }; QueryResult::~QueryResult() { } inline TextQuery::TextQuery(ifstream& ifs) : text(new StrVec, DebugDelete("TextQuery::StrVec")), query_words(new map<string, std::shared_ptr<set<size_t>>>, DebugDelete("TextQuery::map<string, std::shared_ptr<set<size_t>>>")) { size_t size=0; if (ifs) { for (string line; getline(ifs, line,'.'); ++size) { text->push_back(line); istringstream iss(line); size = text->size(); for (string text, word; iss >> text; word.clear()) { std::remove_copy_if(text.begin(), text.end(), std::back_inserter(word), ispunct); // use reference avoid count of shared_ptr add. auto& nos = (*query_words)[word]; if (!nos) nos.reset(new std::set<size_t>); nos->insert(size); } } } } inline std::tuple<string, std::shared_ptr<set<size_t>>, std::shared_ptr<StrVec>> TextQuery::query(string s) const{ static std::shared_ptr<std::set<size_t>> nodate(new std::set<size_t>,DebugDelete("TextQuery::std::set<size_t>")); auto found = query_words->find(s); if (found == query_words->end()) { cout << s + " is not in the text" << endl; return std::tuple<string, std::shared_ptr<set<size_t>>, std::shared_ptr<StrVec>>(s, nodate, text); } else return std::tuple<string, std::shared_ptr<set<size_t>>, std::shared_ptr<StrVec>>(s, found->second, text); } TextQuery::~TextQuery() { }
练习17.4
inline vector<matches> findBook(const vector<vector<Sales_data>>& files, const string& book)
{ vector<matches>ret; for (auto it = files.cbegin(); it != files.cend(); ++it) { auto found = std::equal_range(it->cbegin(), it->cend(), book, [](const Sales_data & lhs, const Sales_data & rhs){return lhs.isbn().compare(rhs.isbn()) > 0;} ); if (found.first != found.second) ret.push_back(std::make_tuple(it - files.cbegin(), found.first, found.second)); } return ret; } inline void reportResults(std::istream& in, std::ostream& os, const std::vector<std::vector<Sales_data>>& files) { std::string s; while (in >> s) { auto trans = findBook(files, s); if (trans.empty()) { std::cout << s << " not found in any stores" << std::endl; continue; } for (const auto& store : trans) os << "store " << std::get<0>(store) << " sales: " << std::accumulate(std::get<1>(store), std::get<2>(store), Sales_data(s))
<< std::endl; }
}
int main(void) {
Sales_data sales_data1("001-01", 1, 100);
Sales_data sales_data2("001-01", 2, 100);
Sales_data sales_data3("001-02", 2, 80);
std::vector<Sales_data> vs1 = { sales_data1, sales_data3 };
std::vector<Sales_data> vs2 = { sales_data2 };
std::vector<std::vector<Sales_data>> vvs = { vs1, vs2 };
reportResults(std::cin, std::cout, vvs);
return 0;
}
练习17.5
typedef std::pair<vector<Sales_data>::size_type, std::pair<vector<Sales_data>::const_iterator, vector<Sales_data>::const_iterator>>matches; inline vector<matches> findBook(const vector<vector<Sales_data>>& files, const string& book) { vector<matches>ret; for (auto it = files.cbegin(); it != files.cend(); ++it) { auto found = std::equal_range(it->cbegin(), it->cend(), book, [](const Sales_data & lhs, const Sales_data & rhs){return lhs.isbn().compare(rhs.isbn()) > 0;} ); if (found.first != found.second) ret.push_back(std::make_pair(it - files.cbegin(), std::make_pair(found.first, found.second))); } return ret; } inline void reportResults(std::istream& in, std::ostream& os, const std::vector<std::vector<Sales_data>>& files) { std::string s; while (in >> s) { auto trans = findBook(files, s); if (trans.empty()) { std::cout << s << " not found in any stores" << std::endl; continue; } for (const auto& store : trans) os << "store " << std::get<0>(store) << " sales: " << std::accumulate(store.second.first, store.second.second, Sales_data(s)) << std::endl; } } int main(void) { Sales_data sales_data1("001-01", 1, 100); Sales_data sales_data2("001-01", 2, 100); Sales_data sales_data3("001-02", 2, 80); std::vector<Sales_data> vs1 = { sales_data1, sales_data3 }; std::vector<Sales_data> vs2 = { sales_data2 }; std::vector<std::vector<Sales_data>> vvs = { vs1, vs2 }; reportResults(std::cin, std::cout, vvs); return 0; }
练习17.6
struct matches { vector<Sales_data>::size_type sz; vector<Sales_data>::const_iterator beg; vector<Sales_data>::const_iterator end; matches(vector<Sales_data>::size_type sz1,vector<Sales_data>::const_iterator beg1,vector<Sales_data>::const_iterator end1):sz(sz1),beg(beg1),end(end1){} }; inline vector<matches> findBook(const vector<vector<Sales_data>>& files, const string& book) { vector<matches>ret; for (auto it = files.cbegin(); it != files.cend(); ++it) { auto found = std::equal_range(it->cbegin(), it->cend(), book, [](const Sales_data & lhs, const Sales_data & rhs){return lhs.isbn().compare(rhs.isbn()) > 0;} ); if (found.first != found.second) ret.emplace_back(it - files.cbegin(), found.first, found.second); } return ret; } inline void reportResults(std::istream& in, std::ostream& os, const std::vector<std::vector<Sales_data>>& files) { std::string s; while (in >> s) { auto trans = findBook(files, s); if (trans.empty()) { std::cout << s << " not found in any stores" << std::endl; continue; } for (const auto& store : trans) os << "store " << store.sz << " sales: " << std::accumulate(store.beg, store.end, Sales_data(s)) << std::endl; } } int main(void) { Sales_data sales_data1("001-01", 1, 100); Sales_data sales_data2("001-01", 2, 100); Sales_data sales_data3("001-02", 2, 80); std::vector<Sales_data> vs1 = { sales_data1, sales_data3 }; std::vector<Sales_data> vs2 = { sales_data2 }; std::vector<std::vector<Sales_data>> vvs = { vs1, vs2 }; reportResults(std::cin, std::cout, vvs); return 0; }
练习17.7
我更倾向tuple来写findBook,因为看起来更易理解
练习17.8
返回的Sales_data中的bookNo成员为空
练习17.9
(a) bitset<64> bitvec(32); // 0000000000000000000000000000000000000000000000000000000000100000 (b) bitset<32> bv(1010101); // 00000000000011110110100110110101 (c) string bstr; cin >> bstr; bitset<8> bv(bstr); // 根据输入的str转换成bitset
练习17.10
int main(void) { std::vector<int> v = { 1, 2, 3, 5, 8, 13, 21 }; std::bitset<32> bit_arr; std::bitset<32> bit_arr1; for (auto i : v) { bit_arr.set(i); bit_arr1[i] = bit_arr[i]; } return 0; }
练习17.11
练习17.12
练习17.13
template<unsigned N> class ans_test { template<unsigned N1, unsigned N2> friend unsigned test(ans_test<N1>& ans, ans_test<N2>& test); public: ans_test(std::string& str):ans(str){} void update_ans(unsigned pos, bool ans) { ans[pos] = ans; } std::ostream& operator<<(std::ostream os) { os << ans; return os; } private: std::bitset<N>ans; }; template<unsigned N1, unsigned N2> unsigned test(ans_test<N1>& ans, ans_test<N2>& test) { if (N1 != N2) { throw("试卷题目数量不符"); } unsigned grade = 0; for (auto i = 0; i < ans.ans.size(); ++i) { if (ans.ans[i] == test.ans[i]) ++grade; } return grade; } int main(void) { std::string s1("0101010101"); std::string s2("0101010111"); ans_test<10> q1(s1); ans_test<10> q2(s2); std::cout << test(q1,q2) << std::endl; return 0; }
练习17.14
int main(void) { try { std::regex r("[[:alnum:]]+\.(cpp|cxx|cc)$", std::regex::icase); std::cmatch results; if (std::regex_search("myfile.cc", results, r)) cout << results.str() << endl; } catch (std::regex_error e) { cout << e.what() << " code: " << e.code() << endl; } return 0; }
练习17.15
int main(void) { cout << "请输入一个待检测的单词:"; string str; try { std::regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", std::regex::icase); while (cin >> str && str != "q") { if (std::regex_search(str, r)) cout << "该单词符合要求:" << str << endl; else cout << "该单词不符合要求:" << str << endl; } } catch (std::regex_error e) { cout << e.what() << " code: " << e.code() << endl; } return 0; }
练习17.16
int main(void) { cout << "请输入一个待检测的单词:"; string str; try { std::regex r("[^c]ei", std::regex::icase); while (cin >> str && str != "q") { if (std::regex_search(str, r)) cout << "该单词符合要求:" << str << endl; else cout << "该单词不符合要求:" << str << endl; } } catch (std::regex_error e) { cout << e.what() << " code: " << e.code() << endl; } return 0; }
练习17.17
int main(int argc,char*argv[]) {string str; ifstream ifs(argv[1]); try { std::regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", std::regex::icase); while (getline(ifs, str)) { for (std::sregex_iterator it(str.begin(), str.end(), r), end_it; it != end_it; ++it) cout << it->str() << endl; } } catch (std::regex_error e) { cout << e.what() << " code: " << e.code() << endl; } return 0; }
练习17.18
int main(int argc,char*argv[]) { string str; ifstream ifs(argv[1]); std::vector<std::string> vec{ "neighbor","albeit","beige","feint","heir","reign","their", "counterfeit","foreign","inveigh","rein","veil","deign", "forfeit","inveigle","seize","veineiderdown","freight", "leisure","skein","weigheight","heifer","neigh","sleigh", "weighteither","height","neighbour","sleight","weirfeign", "heinous","neither","surfeit","weird" }; try { std::regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*", std::regex::icase); while (getline(ifs, str)) { for (std::sregex_iterator it(str.begin(), str.end(), r), end_it; it != end_it; ++it) { if (find(vec.begin(), vec.end(), it->str()) != vec.end()) continue; std::cout << it->str() << std::endl; } } } catch (std::regex_error e) { cout << e.what() << " code: " << e.code() << endl; } return 0; }
练习17.19
如果不匹配,则m[4].str()
返回空字符串。此时号码依然是合法的
练习17.20
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.21
struct PersonInfo { string name; vector<string> phones; }; 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(); } std::vector<std::string> s_split(const std::string& in, const std::string& delim) { std::regex re{ delim }; return std::vector<std::string> { std::sregex_token_iterator(in.begin(), in.end(), re, -1), std::sregex_token_iterator() }; } int main(int argc, char* argv[]) { string line, word; vector<PersonInfo> people; istringstream record; ifstream ifs(argv[1]); std::regex r("(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ]?)(\d{4})"); std::smatch m; std::string s; while (getline(ifs, line)) { record.str(line); PersonInfo info; record >> info.name; while (record >> word) info.phones.push_back(word); record.clear(); people.push_back(info); } for (const auto& person : people) { std::ostringstream formatted, badNums; for (const auto& ph : person.phones) { for (std::sregex_iterator it(ph.begin(), ph.end(), r), end_it; it != end_it; ++it) if (!valid(*it)) { badNums << " " << ph; } else formatted << " " << (*it)[2] << " " << (*it)[2] << (*it)[2]; } if (badNums.str().empty()) cout << person.name << " " << formatted.str() << endl; else std::cerr << " input error: " << person.name << " invalid number(s)" << badNums.str() << endl; } return 0; }
练习17.22
struct PersonInfo { string name; vector<string> phones; }; 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[7].str(); } std::vector<std::string> s_split(const std::string& in, const std::string& delim) { std::regex re{ delim }; return std::vector<std::string> { std::sregex_token_iterator(in.begin(), in.end(), re, -1), std::sregex_token_iterator() }; } int main(int argc, char* argv[]) { string line, word; vector<PersonInfo> people; istringstream record; ifstream ifs(argv[1]); std::regex r("(\()?(\d{3})(\))?([-. ])?([ ]*)?(\d{3})([-. ]?)([ ]*)?(\d{4})"); std::smatch m; std::string s; while (getline(ifs, line)) { record.str(line); PersonInfo info; record >> info.name; while (record >> word) info.phones.push_back(word); record.clear(); people.push_back(info); } for (const auto& person : people) { std::ostringstream formatted, badNums; for (const auto& ph : person.phones) { for (std::sregex_iterator it(ph.begin(), ph.end(), r), end_it; it != end_it; ++it) if (!valid(*it)) { badNums << " " << ph; } else formatted << " " << (*it)[2] << " " << (*it)[2] << (*it)[2]; } if (badNums.str().empty()) cout << person.name << " " << formatted.str() << endl; else std::cerr << " input error: " << person.name << " invalid number(s)" << badNums.str() << endl; } return 0; }
练习17.23
(\d{5})([-])?(\d{4})?
练习17.24
int main() { std::string phone = "(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ]?)(\d{4})"; std::regex r(phone); std::smatch m; std::string s; std::string fmt = "$2.$5.$7"; while (std::getline(std::cin, s)) { std::cout << std::regex_replace(s, r, fmt) << std::endl; } return 0; }
练习17.25
//tx 908.555.1500 (908)5551500 int main() { std::string phone = "(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ]?)(\d{4})*"; std::regex r(phone); std::smatch m; std::string s; std::string fmt = "$2.$5.$7"; while(std::getline(std::cin, s)) { std::smatch result; std::regex_search(s,result,r); if(!result.empty()) { std::cout << result.prefix() << result.format(fmt) << std::endl; } else { std::cout << "Sorry, No match." << std::endl; } } return 0; }
练习17.26
#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[7].str(); } 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)) { std::vector<std::string> vs; for(std::sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it) if(valid(*it)) vs.push_back(it->str()); if (vs.size() == 0) { std::cout << "no matched number" << std::endl; }else if(vs.size() == 1) { std::cout << vs[0] << std::endl; }else if(vs.size() >1) { for(int i = 1; i < vs.size(); ++i) std::cout << vs[i] << " "; std::cout << std::endl; } } return 0; }
练习17.27
bool valid(const std::smatch &m) { if(m[3].matched) return true; else return !m[2].matched; } int main() { std::string mail = "(\d{5})([-])?(\d{4})?"; std::regex r(mail); std::smatch m; std::string s; std::string fmt = "$1-$3"; while(std::getline(std::cin, s)) { std::cout << std::regex_replace(s, r, fmt) << std::endl; } return 0; }
练习17.28
int main() { std::uniform_int_distribution<unsigned>u(0,RAND_MAX); std::default_random_engine e; for (auto i = 0; i < 10; ++i) cout << u(e) << " "; return 0; }
练习17.29
练习17.30
void random(size_t cnt) { std::uniform_int_distribution<unsigned>u(0, RAND_MAX); std::default_random_engine e; for (auto i = 0; i < cnt; ++i) { cout << u(e) << " "; } } void random(size_t cnt,unsigned seed) { std::uniform_int_distribution<unsigned>u(0, RAND_MAX); std::default_random_engine e(seed); for (auto i = 0; i < cnt; ++i) { cout << u(e) << " "; } } void random(size_t cnt,unsigned seed,unsigned max,unsigned min) { std::uniform_int_distribution<unsigned>u(min, max); std::default_random_engine e(seed); for (auto i = 0; i < cnt; ++i) { cout << u(e) << " "; } } int main() { unsigned seed, max, min; cin >> seed >> max >> min; random(10); cout << endl; random(10,seed); cout << endl; random(10,seed,max,min); return 0; }
练习17.31
每次循环都会重置随机数引擎和分布对象,导致每步循环都会生成相同的值
练习17.32
会报错,while
条件中用到了resp
练习17.33
const string& transform(const string& s, const map<string, string>& m) { auto map_iter = m.find(s); if (map_iter != m.end()) { return map_iter->second; } // if find the word in map, return the phrase. else return the origin word. else { return s; } } unordered_map<string, string> buildMap(ifstream& map_file) { unordered_map<string, string> trans_map; string key, value; while (map_file >> key && getline(map_file, value)) { if (value.size() > 1) { trans_map[key] = value.substr(1); // 去掉value前的空格 } else { throw runtime_error("no rules for " + key); } } return trans_map; } const string& transform(const string& s, const unordered_map<string, string>& m) { static std::default_random_engine e(time(0)); static std::uniform_int_distribution<unsigned> u(0, 1); auto map_iter = m.find(s);//当find替换成下标运算符,若关键还未在map中,下标操作会插入一个具有给定关键字的元素 if (map_iter != m.end()) { return string(1,(map_iter->second)[u(e)]); } else { return s; } } void wordTransform(ifstream& map_file, ifstream& input) { auto trans_map = buildMap(map_file); string text; while (getline(input, text)) { istringstream stream(text); string word; bool first_word = true; while (stream >> word) { if (first_word) { first_word = false; } else { cout << " "; } cout << transform(word, trans_map); } cout << endl; } } int main(int argc, char* argv[]) { string transform_file = argv[1]; string input_file = argv[2]; ifstream trans(transform_file); ifstream input(input_file); if (trans && input) { wordTransform(trans, input); } else { cout << "open file error!" << endl; } return 0; }
练习17.34
int main(int argc, char* argv[]) { cout << "alpha bool values: " << std::boolalpha << true << " " << false << " default bool values: " << std::noboolalpha << true << " " << false << endl; cout << std::showbase << "default: " << 20 << " " << 1024 << " in octal: " << std::oct << 20 << " " << 1024 << " in hex: " << std::hex << 20 << " " << 1024 << " in uppercase hex: " << std::uppercase << 20 << " " << 1024 << std::nouppercase << " in decimal: " << std::dec << 20 << " " << 1024 << std::noshowbase << endl; cout << "Precision: " << cout.precision() << ", Value: " << sqrt(2.0) << " Precision: " << cout.precision(12) << ", Value: " << sqrt(2.0) << " Precision: " << std::setprecision(3) << cout.precision() << ", Value: " << sqrt(2.0) << endl; cout << "default format: " << 100 * sqrt(2.0) << " scientific: " << std::scientific << 100 * sqrt(2.0) << " fixed decimal:" << std::fixed << 100 * sqrt(2.0) << " hexadecimal" << std::hexfloat << 100 * sqrt(2.0) << " use defaults" << std::defaultfloat << 100 * sqrt(2.0) << endl; cout << std::showpoint << 10.0 << ' ' << std::noshowpoint << 10.0 << endl; int i = -16; double d = 3.14159; cout << "i: " << std::setw(12) << i << "next col" << ' ' << "d: " << std::setw(12) << d << "next col" << ' '; cout << std::left << "i: " << std::setw(12) << i << "next col" << ' ' << "d: " << std::setw(12) << d << "next col" << ' ' << std::right << "i: " << std::setw(12) << i << "next col" << ' ' << "d: " << std::setw(12) << d << "next col" << ' ' << std::internal << "i: " << std::setw(12) << i << "next col" << ' ' << "d: " << std::setw(12) << d << "next col" << ' ' << std::setfill('#') << "i: " << std::setw(12) << i << "next col" << ' ' << "d: " << std::setw(12) << d << "next col" << ' ' << std::setfill(' '); char ch; cin >> std::noskipws; while (cin >> ch) cout << ch; cin >> std::skipws; return 0; }
练习17.35
int main(int argc, char* argv[]) { cout << std::hexfloat << std::uppercase << sqrt(2.0); }
练习17.36
int main(int argc, char* argv[]) { cout << std::hexfloat << std::uppercase << std::setw(12) << sqrt(2.0) << ' ' << std::hexfloat << std::uppercase << std::setw(12) << sqrt(3.0) << ' ' << std::hexfloat << std::uppercase << std::setw(12) << sqrt(4.0) << ' ' << std::hexfloat << std::uppercase << std::setw(12) << sqrt(5.0) << ' '; }
练习17.37
int main(int argc, char* argv[]) { std::fstream fs(argv[1]); char tmp[200]; while (fs.getline(tmp, 200, ' ')) { std::cout << tmp << std::endl; std::cout << fs.gcount() << std::endl; } }
练习17.38
int main(int argc, char* argv[]) { std::fstream fs(argv[1]); char tmp[200]; while (fs.getline(tmp, 200, ' ')) { std::cout << tmp << std::endl; //std::cout << fs.gcount() << std::endl; } }
练习17.39
int main(int argc, char* argv[]) { std::fstream inOut(argv[1], std::fstream::ate | std::fstream::in | std::fstream::out); if (!inOut) { std::cerr << "Unable to open file!" << std::endl; return EXIT_FAILURE; } auto end_mark = inOut.tellg(); inOut.seekg(0, std::fstream::beg); size_t cnt = 0; std::string line; while (inOut && inOut.tellg() != end_mark && getline(inOut, line)) { cnt += line.size() + 1; auto mark = inOut.tellg(); inOut.seekp(0, std::fstream::end); inOut << cnt; if (mark != end_mark) inOut << " "; inOut.seekg(mark); } inOut.seekp(0, std::fstream::end); inOut << " "; return 0; }