C++ Primer(5e)第11章习题

11.1

map下标是关键字,不必是整数,而vector下标是整数;从map中提取一个元素,会得到一个pair类型对象。

11.3

#include
#include
#include
#include

using namespace std;

int main()
{
	map<string, size_t> word_count;
	set<string> exclude = { "The", "But", "And", "Or", "An", "A",
						   "the", "but", "and", "or", "an", "a" };
	string word;
	while (cin >> word)
	{
		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}
	for (const auto &w : word_count)
		cout << w.first << " occurs " << w.second
		<< ((w.second > 1) ? " times" : " time") << endl;
	return 0;
}

11.4

#include
#include
#include
#include
#include
#include

using namespace std;

int main()
{
	map<string, size_t> word_count;
	set<string> exclude = { "The", "But", "And", "Or", "An", "A",
						   "the", "but", "and", "or", "an", "a" };
	string word;
	while (cin >> word)
	{
		word.erase(find_if(word.begin(), word.end(), ::ispunct), word.end());
		for_each(word.begin(), word.end(), [](char &c) { c = tolower(c); });
		++word_count[word];
	}
	for (const auto &w : word_count)
		cout << w.first << " occurs " << w.second
		<< ((w.second > 1) ? " times" : " time") << endl;
	return 0;
}

11.5

当定义一个map时,必须既指明关键字类型又指明值类型;而定义一个set时,只需指定关键字类型。

11.6

set不能重复,而list可以重复

11.8

#include
#include
#include
#include

using namespace std;

int main()
{
	vector<string> s;
	string word;
	cout << "Enter some strings:" << endl;
	while (cin >> word)
		s.push_back(word);
	sort(s.begin(), s.end());
	auto end_unique = unique(s.begin(), s.end());
	s.erase(end_unique, s.end());
	for (auto c : s)
		cout << c << " ";
	cout << endl;
	return 0;
}

11.9

map<string, list<int>> word_row;

11.10

vector的可以,因为可以使用<
list的不可以,因为不可以使用<

11.11

multiset<Sales_data, bool(compareIsbn)*> bookstore(compareIsbn);

11.12

#include
#include
#include
#include

using namespace std;

int main()
{
	vector<pair<string, int>> anon;
	int i;
	string s;
	while (cin >> s >> i)
		anon.push_back(pair<string, int>(s, i));
	for (const auto &c : anon)
		cout << c.first << " " << c.second << endl;
	return 0;
}

11.13

#include
#include
#include
#include

using namespace std;

int main()
{
	vector<pair<string, int>> anon;
	int i;
	string s;
	while (cin >> s >> i)
		//	anon.push_back(pair(s, i));
		//  anon.push_back(make_pair(s, i));
		anon.emplace_back(s, i);
	for (const auto &c : anon)
		cout << c.first << " " << c.second << endl;
	return 0;
}

11.15

map<int, vector<int>>::mapped_type v1;  // v1是一个vector
map<int, vector<int>>::key_type v2;    //   v2是一个int
map<int, vector<int>>::value_type v3;   // v3是一个pair>

11.16

#include
#include
#include

using namespace std;

int main()
{
	map<int, string> mm = { {1, "abc"} };
	map<int, string>::iterator m_iter = mm.begin();
	m_iter->second = "ABC";
	cout << m_iter->second << endl;
	return 0;
}

11.17

// 合法 
copy(v.begin(), v.end(), inserter(c, c.end()));  
// 非法,只有提供了push_back()函数的容器能使用back_inserter(); 
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));

11.18

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

11.20

#include
#include
#include

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 (const auto &c : word_count)
		cout << c.first << " occurs " << c.second
		<< " times" << endl;
	return 0;
}

11.21

// 对于每个word,插入到容器中,对应的值为0
while (cin >> word)
	++word_count.insert({ word, 0 }).first->second;

11.22

/* 我感觉我写的有问题。。。。*/
#include
#include
#include
#include
#include

using namespace std;

int main()
{
	map<string, vector<int>> v1;
	string s;
	vector<int> v2;
	int i, j = 0;
	while (cin >> s >> i)
	{
		v2.push_back(i);
		pair<map<string, vector<int>>::iterator, bool> ret = v1.insert({ s,v2 });
		if (!ret.second)
			++ret.first->second[j++];
	}
	return 0;
}

11.24

map<int, int> m;
m[0] = 1;
插入一个关键字为0的元素,关联值进行初始化;然后将1赋给它

11.25

vector<int> v;
v[0] = 1;
将vector的首元素赋为1

11.26

可以用key_type对map进行下标操作;返回类型为mapped_type

11.27

想知道容器里该元素出现的次数,用count;
想知道容器里是否有该元素,用find

11.28

#include
#include
#include

using namespace std;

int main()
{
	map<string, vector<int>> v1 = { {"abc", {1, 2, 3}} };
	auto iter = v1.find("abc");
	return 0;
}

11.29

upper_bound返回尾后迭代器
lower_bound返回关键字的第一个安全插入点
equal_bound返回两个迭代器,指向关键字可以插入的位置

11.30

pos保存返回的值,是一个pair
pos.first是pair的第一个成员,是一个对应容器的迭代器
pos.first->解引用此迭代器,提取容器中的元素,元素也是一个pair
pos.first->second容器中元素的值部分

11.31

#include
#include
#include

using namespace std;

int main()
{
	multimap<string, string> authors;
	authors.insert({ "Jim", "book1" });
	authors.insert({ "Jim", "book2" });
	authors.insert({ "David", "book3" });
	auto iter = authors.find("Jim");
	auto entries = authors.count("Jim");
	while (entries--)
		authors.erase(iter++);
	return 0;
}

11.32

#include
#include
#include

using namespace std;

int main()
{
	multimap<string, string> authors;
	authors.insert({ "Jim", "book1" });
	authors.insert({ "Jim", "book2" });
	authors.insert({ "David", "book3" });
	for (auto iter = authors.cbegin(); iter != authors.cend(); ++iter)
		cout << iter->first << " " << iter->second << endl;
	return 0;
}

11.33

/* 把书上代码敲一遍也是极好的 */
#include
#include
#include
#include
#include

using namespace std;

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;        // 完成一行的转换
}

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);
	// 如果单词在转换规则map中
	if (map_it != m.cend())  // 使用替换短语
		return map_it->second;
	else
		return s;    // 否则返回原string
}

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

	return 0;
}

11.34

如果关键字未在容器中,下标操作会插入一个具有给定关键字的元素;而使用find,则不会。

11.35

如果关键字出现多次,使用下标会重复赋值,最后保存的是最后一个值,使用insert只插入第一个。

11.36

if (value.size() > 1)  // 检查是否有转换规则
			trans_map[key] = value.substr(1);  // 跳过前导空格
		else
			throw runtime_error("no rule for " + key);

如果if条件为false,则会抛出错误 “no rule for " + key

你可能感兴趣的:(C++)