练习11.37
一个无序容器与其有序容器版本相比有何优势?有序版本有何优势?
解答:
在关键字类型的元素没有明显的有序关系的情况下,无序容器是非常有用的。在某些应用中,维护元素的序代价非常高昂,此事无需容器也很有用。
虽然理论上哈希技术能获得更好的平均性能,但在实际中想要达到很好的效果还需要进行一些性能测试盒调优工作。因此,使用无序容器通常更为简单。
练习11.38
用unordered_map重写单词计数程序(参见11.1节,第375页)和单词转换程序(参见11.3.6节,第391页)
解答:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <map>
#include <unordered_map>
using namespace std;
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); //跳过前导空格
trans_map.insert({ 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);
// 如果单词在转换规则map中
if (map_it != m.cend()){
return map_it->second; // 使用替换短语
}
else{
return s; // 否则返回原string
}
}
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("map.txt");
ifstream input("input.txt");
word_transform(map_file, input);
}
直接将map替换为unordered_map即可。
对于单词计数程序,在394页已经给出,这里就不再写了。