文章目录
- 练习11.11
- 练习11.12
- 练习11.13
- 练习11.14
- 练习11.15
- 练习11.16
- 练习11.17
- 练习11.18
- 练习11.19
- 练习11.20
练习11.11
不使用decltype 重新定义 bookstore。
using Less = bool (*)(Sales_data const&, Sales_data const&);
std::multiset<Sales_data, Less> bookstore(less);
练习11.12
编写程序,读入string和int的序列,将每个string和int存入一个pair 中,pair保存在一个vector中。
#include <vector>
#include <utility>
#include <string>
#include <iostream>int main()
{std::vector<std::pair<std::string, int>> vec;std::string str;int i;while (std::cin >> str >> i)vec.push_back(std::pair<std::string, int>(str, i));for (const auto &p : vec)std::cout << p.first << ":" << p.second << std::endl;
}
练习11.13
在上一题的程序中,至少有三种创建pair的方法。编写此程序的三个版本,分别采用不同的方法创建pair。解释你认为哪种形式最易于编写和理解,为什么?
vec.push_back(std::make_pair(str, i));
vec.push_back({ str, i });
vec.push_back(std::pair<string, int>(str, i));
使用花括号的初始化器最易于理解和编写。
练习11.14
扩展你在11.2.1节练习中编写的孩子姓达到名的map,添加一个pair的vector,保存孩子的名和生日。
#include <iostream>
#include <map>
#include <string>
#include <vector>using std::ostream;
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::make_pair;
using std::pair;
using std::vector;
using std::map;class Families
{
public:using Child = pair<string, string>;using Children = vector<Child>;using Data = map<string, Children>;void add(string const& last_name, string const& first_name, string birthday){auto child = make_pair(first_name, birthday);_data[last_name].push_back(child);}void print() const{for (auto const& pair : _data){cout << pair.first << ":\n";for (auto const& child : pair.second)cout << child.first << " " << child.second << endl;cout << endl;}}private:Data _data;
};int main()
{Families families;auto msg = "Please enter last name, first name and birthday:\n";for (string l, f, b; cout << msg, cin >> l >> f >> b; families.add(l, f, b));families.print();return 0;
}
练习11.15
对一个int到vector的map,其mapped_type、key_type和 value_type分别是什么?
- mapped_type : vector
- key_type : int
- value_type : std::pair<const int,vector >
练习11.16
使用一个map迭代器编写一个表达式,将一个值赋予一个元素。
std::map<int, string>::iterator it = m.begin();
it->second = "hello";
练习11.17
假定 c 是一个string的multiset,v 是一个string 的vector,解释下面的调用。指出每个调用是否合法:
copy(v.begin(), v.end(), inserter(c, c.end()));
copy(v.begin(), v.end(), back_inserter(c));
copy(c.begin(), c.end(), inserter(v, v.end()));
copy(c.begin(), c.end(), back_inserter(v));
第二个调用不合法,因为 multiset 没有 push_back 方法。其他调用都合法。
练习11.18
写出第382页循环中map_it 的类型,不要使用auto 或 decltype。
map<string, size_t>::const_iterator map_it = word_count.cbegin();
练习11.19
定义一个变量,通过对11.2.2节中的名为 bookstore 的multiset 调用begin()来初始化这个变量。写出变量的类型,不要使用auto 或 decltype。
using compareType = bool (*)(const Sales_data &lhs, const Sales_data &rhs);
std::multiset<Sales_data, compareType> bookstore(compareIsbn);
std::multiset<Sales_data, compareType>::iterator c_it = bookstore.begin();
练习11.20
重写11.1节练习的单词计数程序,使用insert代替下标操作。你认为哪个程序更容易编写和阅读?解释原因。
#include <iostream>
#include <map>
#include <string>using std::string;
using std::map;
using std::cin;
using std::cout;int main()
{map<string, size_t> counts;for (string word; cin >> word;){auto result = counts.insert({ word, 1 });if (!result.second)++result.first->second;}for (auto const& count : counts)cout << count.first << " " << count.second << ((count.second > 1) ? " times\n" : " time\n");return 0;
}
使用 insert 更容易阅读和编写。insert 有返回值,可以明确的体现出插入操作的结果。