C++Primer第五版——习题答案详解(十)


习题答案目录:https://www.cnblogs.com/Mered1th/p/10485695.html

第11章 关联容器


练习11.3

#include<iostream>
#include<string>
#include<map>

using namespace std;

int main() {
	string s;
	map<string, size_t> num;
	cout << "输入单词表:" << endl;
	while (cin >> s) {
		++num[s];
	}
	for (const auto &i : num) {
		cout << i.first << " occurs " << i.second << ((i.second > 1) ? " times" : " time") << endl;
	}

	system("pause");
	return 0;
}

练习11.4

#include<iostream>
#include<string>
#include<map>
#include<cctype>
using namespace std;

void process(string &s) {
	for (auto i = 0;i < s.size(); ++i) {
		if (isupper(s[i])) s[i] = tolower(s[i]);
		else if (ispunct(s[i])) {
			s.erase(i,1);
		}
	}
}

int main() {
	string s;
	map<string, size_t> num;
	cout << "输入单词表:" << endl;
	while (cin >> s) {
		process(s);
		++num[s];
	}
	for (const auto &i : num) {
		cout << i.first << " occurs " << i.second << ((i.second > 1) ? " times" : " time") << endl;
	}

	system("pause");
	return 0;
}

练习11.7

#include<map>
#include<vector>
#include<iostream>
#include<string>

using namespace std;

int main() {
	map<string, vector<string>> mp;
	string last_name, first_name;
	cout << "输入姓:" << endl;
	cin >> last_name;
	cout << "输入该姓的成员名字:" << endl;
	while (cin >> first_name) {
		mp[last_name].push_back(first_name);
	}
	for (const auto i : mp) {
		cout << "姓:" << i.first << " 有以下成员:" << endl;
		for (const auto j : i.second) {
			cout << j << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

练习11.8

#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

int main() {
	vector<int> v = { 1,1,2,3,4,4,5,6 };
	auto iter = unique(v.begin(), v.end());
	v.erase(iter, v.end());
	for (auto i : v) {
		cout << i << " ";
	}
	cout << endl;
	system("pause");
	return 0;
}

练习11.9

map<string, list<size_t>> mp;

练习11.10
vector可以,因为定义了比较大小的操作,list未定义所以不行。

练习11.11

using compareType = bool (*)(const Sales_data& lhs, const Sales_data& rhs);

练习11.12

#include<vector>
#include<utility>
#include<iostream>
#include<string>
using namespace std;

int main() {
	vector<pair<string,int>> vec;
	size_t i = 0;
	string s;
	int num;
	while (cin >> s >> num) {
		vec.push_back({ s,num });
		++i;
	}
	for (auto i : vec) {
		cout << i.first << " " << i.second << endl;
	}
	system("pause");
	return 0;
}

练习11.13

#include<vector>
#include<utility>
#include<iostream>
#include<string>
using namespace std;

int main() {
	vector<pair<string,int>> vec;
	size_t i = 0;
	string s;
	int num;
	while (cin >> s >> num) {
		//vec.push_back({ s,num }); 第一种
		vec.emplace_back(s, num); //第二种:最简便
		//vec.push_back(make_pair(str,i));//第三种
		++i;
	}
	for (auto i : vec) {
		cout << i.first << " " << i.second << endl;
	}
	system("pause");
	return 0;
}

练习11.14

#include<map>
#include<vector>
#include<iostream>
#include<string>
#include<utility>
using namespace std;

int main() {
	map<string, vector<pair<string,string>>> mp;
	string last_name, first_name, birthday;
	cout << "输入姓:" << endl;
	cin >> last_name;
	cout << "输入该姓的成员名字和生日:" << endl;
	while (cin >> first_name >> birthday) {
		mp[last_name].emplace_back(first_name, birthday);
	}
	for (const auto i : mp) {
		cout << "姓:" << i.first << " 有以下成员:" << endl;
		for (const auto j : i.second) {
			cout << j.first << " " << j.second << endl;
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

练习11.15
mapped_type 是vector
key_type 是int
value_type 是pair<int,vector>

练习11.16

#include<map>
#include<iostream>
#include<string>

using namespace std;

int main() {
	map<string, int> mp;
	mp["aaa"] = 1;
	auto iter = mp.begin();
	iter->second = 2;
	//iter->first = "bbb"; const 不允许修改
	cout << iter->first << " " << iter->second << endl;
	system("pause");
	return 0;
}

练习11.17
第三个不合法,back_inserter()需要用到push_back(),而set没有;其余合法。

练习11.18

map<const string,size_t>::iterator

练习11.19

using compareType = bool (*)(const Sales_data &lhs, const Sales_data &rhs);
multiset<Sales_data, compareType> bookstore(compareIsbn);
multiset<Sales_data, compareType>::iterator c_it = bookstore.begin();

练习11.20

#include<iostream>
#include<string>
#include<map>

using namespace std;

int main() {
	map<string, size_t> word_count;
	string word;
	while (cin >> word) {
		auto ret = word_count.insert({ word,1 });
		if (!ret.second) {
			++ret.first->second;
		}
	}
	for (auto i : word_count) {
		cout << i.first << " " << i.second << endl;
	}

	system("pause");
	return 0;
}

之前的更容易阅读和编写。

练习11.21

word_count.insert({ word,0 }) //得到insert的返回值,是一个pair
word_count.insert({ word,0 }).first //是pair的第一个成员,是一个map迭代器,指向具有给定关键字的元素
word_count.insert({ word,0 }).first -> //解引用此迭代器,提取map中的元素,元素也是一个pair
word_count.insert({ word,0 }).first -> second //map中元素的值部分
++word_count.insert({ word,0 }).first->second //递增此值

练习11.23

#include<map>
#include<vector>
#include<iostream>
#include<string>
using namespace std;

int main() {
	multimap<string, vector<string>> mp;
	vector<string> vs;
	string last_name, first_name;
	cout << "总共有几个姓:" << endl;
	int n, k = 1;
	cin >> n;
	while (n--) {
		cout << "请输入第" << k << "个姓:" << endl;
		cin >> last_name;
		cout << "请输入姓" << last_name << "的成员,并以  END  结束当前输入" << endl;
		while (cin >> first_name) {
			if(first_name!="END") vs.push_back(first_name);
			else break;
		}
		mp.insert({ last_name,vs });
		k++;
	}
	for (const auto i : mp) {
		cout << "姓:" << i.first << " 有以下成员:";
		for (const auto j : i.second) {
			cout << j << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

练习11.28

#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;

int main() {
	map<string, vector<int>> mp = { { "aa",{1,2,3,4} } };
	auto iter = mp.find("aa");
	cout << iter->first << endl;
	system("pause");
	return 0;
}

练习11.29
upper_bound和lower_bound返回相等的迭代器——指向一个不影响排序的关键字插入位置。

练习11.30
第一个迭代器引用后得到书名。

练习11.31

#include<iostream>
#include<map>
#include<string>

using namespace std;

int main() {
	string search_item = "bbb";
	multimap < string, string > mp = { {"John", "aaa"}, { "John","bbb" }, { "John","ccc" },{"Tom","ddd"} };
	auto iter = mp.find("John");
	auto num = mp.count("John");
	while (num) {
		if (iter->second == search_item) {
			mp.erase(iter);
			break;
		}
		++iter;
		--num;
	}
	for (auto i : mp) {
		cout << i.first << " " << i.second << endl;
	}
	system("pause");
	return 0;
}

练习11.32

#include<iostream>
#include<map>
#include<string>
#include<set>

using namespace std;

int main() {
	string search_item = "bbb";
	multimap < string, string > mp = { {"John", "baa"}, { "John","abb" }, { "John","ced" },{"Tom","ccc"},{"Bob","zzz"},{"Bob","aae"} };
	map<string, set<string>> ans;
	for (auto i : mp) {
		ans[i.first].insert(i.second);
	}
	for (auto i : ans) {
		cout << i.first << " : ";
		for (auto j : i.second) {
			cout << j << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

练习11.33

#include<iostream>
#include<string>
#include<map>
#include<fstream>
#include<sstream>

using namespace std;

//函数buildMap读入给定文件,建立起转换映射
map<string, string> buildMap(ifstream &map_file) {
	map<string, string> trans_map;
	string key;
	string value;
	//读取第一个单词存入key中,行中剩余内容存入value
	while (map_file >> key && getline(map_file, value)) {
		if (value.size() > 1) {
			trans_map[key] = value.substr(1); //跳过前导空格
		}
		else {
			throw runtime_error("no rule for " + key);
		}
	}
	return trans_map;
}

//生成文本转换
const string & transform(const string &s, const map<string, string> &m) {
	auto map_it = m.find(s);
	if (map_it != m.cend()) {
		return map_it->second;
	}
	else {
		return s;
	}
}

void word_transform(ifstream &map_file, ifstream &input) {
	auto trans_map = buildMap(map_file);//保存转换规则
	string text;
	while (getline(input, text)) {
		istringstream stream(text); //读取每个单词
		string word;
		bool firstword = true;  //控制是否打印空格
		while (stream >> word) {
			if (firstword) {
				firstword = false;
			}
			else cout << " ";
			//transform返回它的第一个参数或其转换之后的形式
			cout << transform(word, trans_map); 
		}
		cout << endl;
	}
}

int main() {
	ifstream map_file("book.txt"), input("test.txt");
	word_transform(map_file, input);
	system("pause");
	return 0;
}

练习11.34
下标操作,当元素不存在时会隐式地创建一个新元素插入到map中,修改了map

练习11.35
如果有重复的key,则下标表示时新的会替换旧的,而insert不会,那么在transform函数中find会有多个返回值导致出错。

练习11.36

#include<iostream>
#include<string>
#include<map>
#include<fstream>
#include<sstream>

using namespace std;

//函数buildMap读入给定文件,建立起转换映射
map<string, string> buildMap(ifstream &map_file) {
	map<string, string> trans_map;
	string key;
	string value;
	//读取第一个单词存入key中,行中剩余内容存入value
	while (map_file >> key && getline(map_file, value)) {
		if (value.size() > 1) {
			trans_map[key] = value.substr(1); //跳过前导空格
		}
		else {
			throw runtime_error("no rule for " + key);
		}
	}
	return trans_map;
}

//生成文本转换
const string & transform(const string &s, const map<string, string> &m) {
	auto map_it = m.find(s);
	if (map_it != m.cend()) {
		return map_it->second;
	}
	else {
		return s;
	}
}

void word_transform(ifstream &map_file, ifstream &input) {
	auto trans_map = buildMap(map_file);//保存转换规则
	string text;
	while (getline(input, text)) {
		istringstream stream(text); //读取每个单词
		string word;
		bool firstword = true;  //控制首个空格
		while (stream >> word) {
			if (firstword) {
				firstword = false;
			}
			else cout << " ";
			//transform返回它的第一个参数或其转换之后的形式
			cout << transform(word, trans_map); 
		}
		cout << endl;
	}
}

int main() {
	ifstream map_file("book.txt"), input("test.txt");
	word_transform(map_file, input);
	system("pause");
	return 0;
}

练习11.37
无序容器不用排序,效率高。
有序容器可以自定义排序。

练习11.38
单词计数程序

#include <unordered_map>
#include <string>
#include <iostream>

using namespace std;

int main()
{
	unordered_map<string, size_t> word_count;
	string word;
	while(cin >> word)
		++word_count[word];

	for(const auto &w : word_count)
		cout << w.first << "," << w.second << endl;

	return 0;
}

单词转换程序

#include<iostream>
#include<string>
#include<unordered_map>
#include<fstream>
#include<sstream>

using namespace std;

//函数buildMap读入给定文件,建立起转换映射
unordered_map<string, string> buildMap(ifstream &map_file) {
	unordered_map<string, string> trans_map;
	string key;
	string value;
	//读取第一个单词存入key中,行中剩余内容存入value
	while (map_file >> key && getline(map_file, value)) {
		if (value.size() > 1) {
			trans_map[key] = value.substr(1); //跳过前导空格
		}
		else {
			throw runtime_error("no rule for " + key);
		}
	}
	return trans_map;
}

//生成文本转换
const string & transform(const string &s, const unordered_map<string, string> &m) {
	auto map_it = m.find(s);
	if (map_it != m.cend()) {
		return map_it->second;
	}
	else {
		return s;
	}
}

void word_transform(ifstream &map_file, ifstream &input) {
	auto trans_map = buildMap(map_file);//保存转换规则
	string text;
	while (getline(input, text)) {
		istringstream stream(text); //读取每个单词
		string word;
		bool firstword = true;  //控制首个空格
		while (stream >> word) {
			if (firstword) {
				firstword = false;
			}
			else cout << " ";
			//transform返回它的第一个参数或其转换之后的形式
			cout << transform(word, trans_map); 
		}
		cout << endl;
	}
}

int main() {
	ifstream map_file("book.txt"), input("test.txt");
	word_transform(map_file, input);
	system("pause");
	return 0;
}
posted @ 2019-03-17 11:54  Mered1th  阅读(929)  评论(0编辑  收藏  举报