C++Primer第五版 习题答案 第十一章关联容器

11.1

map是关联式容器,元素式按关键字保存和访问的;
vector是顺序容器,其元素是按照它在容器中的位置来保存和访问的;

11.2

list:插入较多情况;
vector:动态数组;
deque:需要头部和尾部增删的情况;
map:字典;
set:添加忽略关键字;

11.3

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

using namespace std;

int main() {
	map<string, size_t> word_count;
	string words;
	while (cin>>words)
	{
		++word_count[words];
	}
	for (const auto &s : word_count)
		cout << s.first << " occurs  " << s.second << ((s.second > 1) ? " times " : " time ") << endl;
	return 0;
}

11.4

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

using namespace std;

int main() {
	map<string, size_t> word_count;
	set<string>exclude{ "you","i" };
	string words;
	
	while (cin>>words)
	{
		words.erase(find_if(words.begin(), words.end(), ::ispunct), words.end()); //删除单词后面的标点
		for_each(words.begin(), words.end(), [](char& c) {c = tolower(c); }); //单词转换为小写
		if(exclude.find(words)==exclude.end()) //忽略部分单词
			++word_count[words];
	}
	for (const auto &s : word_count)
		cout << s.first << " occurs  " << s.second << ((s.second > 1) ? " times " : " time ") << endl;
	return 0;
}


11.5

set中只有关键字;
map包括关键字-值对;

11.6

set关联式容器,查找较快;
list顺序容器,查找关键字与容器的大小有关;

11.7

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

using namespace std;

int main() {
	map<string, vector<string>>	family;
	string first_name, last_name;
	cin >> last_name;
	while (cin >> first_name)
	{
		family[last_name].push_back(first_name);
	}
	for (const auto f : family) {
		cout << f.first << endl;
		for (const auto s : f.second)
			cout << s << " ";
		cout << endl;
	}
	return 0;
}

11.8

效率更高,不用遍历判断重复;

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

using namespace std;

int main() {
	vector<string>vs;
	string s;
	while (cin >>s)
	{
		if (find(vs.begin(), vs.end(), s) == vs.end())
			vs.push_back(s);
	}
	for (const auto s : vs)
		cout << s << " ";
	cout << endl;
	return 0;
}

11.9

map<string,list<size_t>> words_line;

11.10

对于有序容器必须定义元素的比较方法,默认<;
vector<int>::iterator 可以,因为定义了<;
list<int>::iterator不可以,未定义<;

11.11

#include <set>
#include <iostream>
#include <string>
#include "../ch07_Classes/Sales_data_ex26.h"

bool compareIsbn(const Sales_data &sales_data1, const Sales_data &sales_data2)
{
	return sales_data1.isbn() < sales_data2.isbn();
}

int main()
{
	using COMPAREISBN = bool (*)(const Sales_data &sales_data1, const Sales_data &sales_data2);
	// std::multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
	std::multiset<Sales_data, COMPAREISBN> bookstore(compareIsbn);
	return 0;
}

11.12

#include<iostream>
#include<string>
#include<vector>
#include<utility>

using namespace std;

int main() {
	vector<pair<string, int>>vp;
	int i;
	string s;
	while (cin>>s>>i)
	{
		//vp.push_back(pair<string, int>(s, i));
		//vp.push_back({ s,i });
		vp.push_back(make_pair(s, i));
		//vp.emplace_back(s, i);

	}
	for (const auto p : vp)
		cout << p.first << " " << p.second << endl;
	return 0;
}

11.13

#include<iostream>
#include<string>
#include<vector>
#include<utility>

using namespace std;

int main() {
	vector<pair<string, int>>vp;
	int i;
	string s;
	while (cin>>s>>i)
	{
		//vp.push_back(pair<string, int>(s, i));
		//vp.push_back({ s,i });
		vp.push_back(make_pair(s, i));
		//vp.emplace_back(s, i);

	}
	for (const auto p : vp)
		cout << p.first << " " << p.second << endl;
	return 0;
}

11.14

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

using namespace std;

int main() {
	map<string, vector<pair<string, string>>>	family;
	string first_name, last_name, birthday;
	cin >> last_name;
	while (cin >> first_name >> birthday)
	{
		family[last_name].push_back(make_pair(first_name, birthday));
		for (const auto f : family) {
			cout << f.first << endl;
			for (const auto s : f.second)
				cout << s.first << " " << s.second << endl;
		}
		return 0;
	}
}

11.15

mapped_type: vector<int>
key_type: int;
value_type: pair<const int,vector<int>>

11.16

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

using namespace std;

int main() {
	map<int, string> m = { {1,"aa" } };
	auto m_iter = m.begin();
	m_iter->second = "bb";
	cout << m_iter->first << " " << m_iter->second << endl;
	return 0;
}

11.17

copy(v.begin(), v.end(), inserter(c, c.end())); //合法
copy(v.begin(), v.end(), back_inserter(c)); //非法,set中没有push_back()
copy(c.begin(), c.end(), inserter(v, v.end())); //合法
copy(c.begin(), c.end(), back_inserter(v)); //合法

11.18

map<string,size_t>::const_iterator map_it =word_count.cbegin();

11.19

using COMPAREISBN = bool (*)(const Sales_data &sales_data1, const Sales_data &sales_data2);
// std::multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
std::multiset<Sales_data, COMPAREISBN> bookstore(compareIsbn);
std::multiset<Sales_data, COMPAREISBN>::iterator bookstore_iter = bookstore.begin();

11.20

使用下标更加简单;

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

using namespace std;

int main() {
	map<string, size_t>word_count;
	string word;
	while (cin>>word)
	{
		pair<map<string, size_t>::iterator, bool> ret = word_count.insert({ word,1 });
		if (!ret.second)
			++ret.first->second;
	}

	for (const auto s : word_count)
		cout << s.first << " " << s.second << endl;
	return 0;
}

11.21

word_count.insert({word, 0})//得到insert的返回值pair
word_count.insert({word, 0}).first//得到map的迭代器
word_count.insert({word, 0}).first->second//map中size_t的值
++word_count.insert({word, 0}).first->second//递增该值

11.22

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

using namespace std;

int main() {
	map<string, vector<int>> m1;
	pair<map<string, vector<int>>::iterator, bool> ret = m1.insert({ "aaaa",{1,2,3,4,5}});
	return 0;
}

11.23

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

using namespace std;

int main() {
	multimap<string, vector<string>>	family;
	string first_name, last_name;
	vector<string>vs;
	cin >> last_name;
	while (cin>>first_name)
	{
		vs.push_back(first_name);
	}
	family.insert({ last_name,vs });

	for (const auto f : family) {
		cout << f.first << endl;
		for (const auto s : f.second)
			cout << s << " ";
		cout << endl;
	}
	return 0;
}

11.24

向m中添加一个关键字为0的元素,并将其值初始化为1;

11.25

将容器第一个元素赋值为1;

11.26

可以用key_type对一个map进行下标操作;
下标操作返回mapped_type;

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

using namespace std;

int main() {
	map<int, string>m1 { {1, "dasda"} };
	map<int, string>::key_type i1 = 1;
	map<int, string>::mapped_type s1;
	s1 = m1[i1];
	cout << i1 << " " << s1 << endl;
	return 0;
}

11.27

统计该元素有多少关键字用count
查看特定元素是否在容器内用find;

11.28

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

using namespace std;

int main() {
	map<string, vector<int>>m1{ {"aa",{1,2,3}} };
	map<string, vector<int>>::iterator i_iter = m1.find("aa");
	return 0;
}

11.29

lower_bound和upper_bound会返回相等的迭代器——都指向给定关键字的插入点,能保持容器中元素顺序的插入位置;
equal_range返回一个pair,pair中两个迭代器都指向元素可以插入的位置;

11.30

第一个迭代器的解引用后得到的书名;

11.31

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


using namespace std;

int main() {
	multimap<string, string>m{ {"a","abc"},{"a","avb"} };
	auto cnt = m.count("a");
	cout << cnt << endl;
	while (cnt)
	{
		m.erase(m.find("a"));
		--cnt;
	}
	for (const auto & s : m)
		cout << s.first << " " << s.second << endl;
	return 0;
}

11.32

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

using namespace std;

int main() {
	multimap<string, string>m{ {"a","abc"},{"a","avb"},{"b","dasdsa"},{"b","sdad"},{"c","fdsdfds"}};
	map<string, vector<string>> m_ordered;
	for (const auto p : m)
		m_ordered[p.first].push_back(p.second);

	for (const auto& p : m_ordered)
	{
		cout << p.first << endl;
		for (const auto s : p.second)
			cout << s << " ";
		cout << endl;
	}
	return 0;
}

11.33

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

using namespace std;

map<string, string> buildMap(ifstream &map_file)
{
	map<string, string> trans_map;
	string key;
	string 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_tranform(ifstream &map_file, ifstream &input)
{
	auto trans_map = buildMap(map_file);
	// for(const auto p : trans_map)
	// 	cout << p.first << "->" << p.second << endl;
	string text;
	while(getline(input, text))
	{
		istringstream stream(text);
		string word;
		bool firstword = true;
		while(stream >> word)
		{
			if(firstword)
				firstword = false;
			else
				cout << " ";
			cout << transform(word, trans_map);
		}
		cout << endl;
	}
}

int main()
{
	ifstream map_file("word_transformation.txt"), input("word_transformation_bad.txt");
	word_tranform(map_file, input);

	return 0;
}

11.34

当map中没有这个元素时会插入元素,与预期不符;

11.35

在这里没有影响,如果关键字出现多次,使用下标会重复赋值,最后保存的是最后一个值,使用insert只插入第一个;

11.36

value.size() > 1 为false,将会抛出异常“no rule for” + key;

11.37

无序容器会有更好地平均性能;

11.38

单词计数程序;

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

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 << " occurs " <<w.second<< ((w.second > 1) ? " times" : " time") << endl;
	return 0;
}

单词转换程序

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

using namespace std;

unordered_map<string, string> buildMap(ifstream &map_file)
{
	unordered_map<string, string> trans_map;
	string key;
	string 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_tranform(ifstream &map_file, ifstream &input)
{
	auto trans_map = buildMap(map_file);
	// for(const auto p : trans_map)
	// 	cout << p.first << "->" << p.second << endl;
	string text;
	while(getline(input, text))
	{
		istringstream stream(text);
		string word;
		bool firstword = true;
		while(stream >> word)
		{
			if(firstword)
				firstword = false;
			else
				cout << " ";
			cout << transform(word, trans_map);
		}
		cout << endl;
	}
}

int main()
{
	ifstream map_file("word_transformation.txt"), input("word_transformation_bad.txt");
	word_tranform(map_file, input);

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值