第十一章 关联容器
11.2 有序容器前置知识
- 练习11.7
有序容器对key的要求
key必须定义比较的方法,默认为<
有序容器的第二个模板参数就是一个用来比较的函数对象,默认是less<Key>()
(函数名会被当做函数指针处理,所以函数名、&函数名或decltype(函数名)*都是一样的效果)
- 练习11.10
注意key能否比较,显然list的迭代器是双向迭代器不是随机访问迭代器所以不能作mapkey
pair类型
定义在<utility>中
介绍这个类型的目的是了解map系列的元素类型
- 练习11.12
可以临时用s和i构造pair,或者用emplace_back,或者make_pair
11.3 关联容器操作
key_type不用解释,mapped_type就是map中value的类型,而value_type则看容器实现
由于key不允许改变,因此map pair的first元素是const
迭代器
由于key不允许改变,指向const部分的都是const迭代器
一般不对关联容器使用STL算法
添加元素
非multi版本容器不会添加具有重复关键字的元素
删除元素
erase有删除指定key的版本,返回值是删除的元素数量,若为0则说明元素不在容器里
map下标
下标为容器中不存在的key时将添加元素,这点和顺序容器、数组都不一样
查找元素
find和count接口是很容易理解的,这里着重提一下后面三个成员:
综合应用
使用预定规则(文件1)转换给定文件(文件2)的文本,涉及map的创建、搜索、遍历
//对单词进行处理
const string &transform(const string &s, const map<string, string> &m) {
auto map_it = m.find(s);
if (map_it != m.end())
return map_it->second;
else
return s;
}
//给定规则文件建立词典
map<string, string> buildMap(ifstream &map_file) {
map<string, string> trans_map;
string 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;
}
//给规则文件和待处理文件进行处理
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 << " ";
cout << transform(word, trans_map);
}
cout << endl;
}
}
int main() {
ifstream ifs("in.txt"), rfs("1.txt");
word_transform(ifs, rfs);
// where are you
// you dont send me a picture
// okay? thanks! l8r
}
当然使用规则文件建立词典的过程还很粗糙,如果文件有空白行或者规则不完整呢?
11.4 无序容器
无序容器使用哈希函数将元素映射到桶中,哈希值相同或者key相同会被存放在一处
其他操作跟关联容器类似,但有下列对桶和哈希进行调整的操作
如果不需要对key进行排序或者哈希可以解决存储问题,无序容器通常比有序容器使用代价小
第十一章结束~