C++ Primer第五版_第十一章习题答案(31~38)
文章目录
- 练习11.31
- 练习11.32
- 练习11.33
- 练习11.34
- 练习11.25
- 练习11.36
- 练习11.37
- 练习11.38
练习11.31
编写程序,定义一个作者及其作品的multimap。使用find在multimap中查找一个元素并用erase删除它。确保你的程序在元素不在map 中时也能正常运行。
#include <map>
#include <string>
#include <iostream>
using std::string;
int main()
{
std::multimap<string, string> authors{
{ "alan", "DMA" },
{ "pezy", "LeetCode" },
{ "alan", "CLRS" },
{ "wang", "FTP" },
{ "pezy", "CP5" },
{ "wang", "CPP-Concurrency" } };
string author = "pezy";
string work = "CP5";
auto found = authors.find(author);
auto count = authors.count(author);
while (count)
{
if (found->second == work)
{
authors.erase(found);
break;
}
++found;
--count;
}
for (const auto &author : authors)
std::cout << author.first << " " << author.second << std::endl;
return 0;
}
练习11.32
使用上一题定义的multimap 编写一个程序,按字典序打印作者列表和他们的作品。
#include <map>
#include <set>
#include <string>
#include <iostream>
using std::string;
int main()
{
std::multimap<string, string> authors{
{ "alan", "DMA" },
{ "pezy", "LeetCode" },
{ "alan", "CLRS" },
{ "wang", "FTP" },
{ "pezy", "CP5" },
{ "wang", "CPP-Concurrency" } };
std::map<string, std::multiset<string>> order_authors;
for (const auto &author : authors)
order_authors[author.first].insert(author.second);
for (const auto &author : order_authors)
{
std::cout << author.first << ": ";
for (const auto &work : author.second)
std::cout << work << " ";
std::cout << std::endl;
}
return 0;
}
练习11.33
实现你自己版本的单词转换程序。
#include <iostream>
#include <map>
#include <fstream>
#include <sstream>
using namespace std;
void word_transform(ifstream&, ifstream&);
map<string, string> buildMap(ifstream&);
string transform(const string&, map<string, string>&);
int main()
{
ifstream ifs_rules("./data/transform_rules.txt");
ifstream ifs_txt("./data/for_transform.txt");
word_transform(ifs_rules, ifs_txt);
return 0;
}
void word_transform(ifstream& rule_file, ifstream& input)
{
auto rule_map = buildMap(rule_file);
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, rule_map);
}
cout << endl;
}
}
map<string, string> buildMap(ifstream& rule_file)
{
map<string, string> m;
string key;
string value;
while (rule_file >> key && getline(rule_file, value))
{
if (value.size() > 1)
m[key] = value.substr(1);
else
throw runtime_error("no rule for " + key);
}
return m;
}
string transform(const string& s, map<string, string>& m)
{
auto it = m.find(s);
if (it != m.cend())
return it->second;
else
return s;
}
练习11.34
如果你将transform 函数中的find替换为下标运算符,会发生什么情况?
如果使用下标运算符,当关键字未在容器中时,会往容器中添加一个新元素。
练习11.25
在buildMap中,如果进行如下改写,会有什么效果?
trans_map[key] = value.substr(1);
//改为
trans_map.insert({key, value.substr(1)});
当一个转换规则的关键字多次出现的时候,使用下标运算符会保留最后一次添加的规则,而用insert则保留第一次添加的规则。
练习11.36
我们的程序并没检查输入文件的合法性。特别是,它假定转换规则文件中的规则都是有意义的。如果文件中的某一行包含一个关键字、一个空格,然后就结束了,会发生什么?预测程序的行为并进行验证,再与你的程序进行比较。
如果关键字没有对应的规则,那么程序会抛出一个 runtime_error
。
练习11.37
一个无序容器与其有序版本相比有何优势?有序版本有何优势?
无序容器拥有更好的性能,有序容器使得元素始终有序。
练习11.38
用 unordered_map 重写单词计数程序和单词转换程序。
#include <iostream>
#include <unordered_map>
#include <fstream>
#include <sstream>
using namespace std;
void word_transform(ifstream&, ifstream&);
unordered_map<string, string> buildMap(ifstream&);
string transform(const string&, unordered_map<string, string>&);
int main()
{
ifstream ifs_rules("H:/code/C++/Cpp_Primer_Answers/data/transform_rules.txt");
ifstream ifs_txt("H:/code/C++/Cpp_Primer_Answers/data/for_transform.txt");
word_transform(ifs_rules, ifs_txt);
return 0;
}
void word_transform(ifstream& rule_file, ifstream& input)
{
auto rule_map = buildMap(rule_file);
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, rule_map);
}
cout << endl;
}
}
unordered_map<string, string> buildMap(ifstream& rule_file)
{
unordered_map<string, string> m;
string key;
string value;
while (rule_file >> key && getline(rule_file, value))
{
if (value.size() > 1)
m[key] = value.substr(1);
else
throw runtime_error("no rule for " + key);
}
return m;
}
string transform(const string& s, unordered_map<string, string>& m)
{
auto it = m.find(s);
if (it != m.cend())
return it->second;
else
return s;
}