关联容器: 添加元素
2023年12月26日 2023年12月28日
和顺序容器添加元素相比较
顺序容器 | 关联容器 |
---|---|
指定位置插入元素: push_back/push_front/emplace_back/emplace_front/insert(p, val)/emplace(p, args) | X; 关联容器元素的存储位置只与关键字有关,指定位置没有意义; 有序关联容器有时会给出指示位置 |
插入若干个相同元素: insert(p, n, t) | X; 部分关联容器不允许关键字重复; 允许关键字重复的关联容器对相等关键字进行计数; 插入若干个相同元素没有意义 |
添加元素: insert(val) /emplace(args) | O |
添加迭代器范围给出的元素序列: insert(b, e) | O |
添加初始化列表给出的元素序列: insert({vals}) | O |
insert和emplace均为成员函数
map, set, unordered_map, unordered_set不允许关键字重复: 只有当元素的关键字不在容器中时才添加
有序关联容器的元素按关键字有序排列: 给出指示位置, 即从指示位置开始搜索新元素的存储位置, 可以省去一些开销
使用insert成员函数添加元素
向容器中添加单个元素或元素序列
- 接受元素类型对象
- 接受迭代器范围
- 接受初始化列表
- 接受元素类型对象和一个指示位置(指出从哪里开始搜索存储新元素的位置)
添加序列时: 对于一个给定的关键字,只有第一个带此关键字的元素被添加到容器中
1c.insert(v); // v是value_type 2 3c.insert(b, e); 4// b和e是迭代器,表示c::value_type类型值的范围 5// 返回void 6 7c.insert(il); 8// il是c::value_type类型值的列表(不允许精度丢失, 可以int转double, 不能double转int) 9// 返回void 10 11c.insert(p, v); 12// p作为一个提示, 指出从哪里开始搜索新元素应该存储的位置; 返回一个迭代器,指向具有给定关键字的元素
示例
-
set
1vector<int> ivec = {2, 4, 6, 8, 2, 4, 6, 8}; 2set<int> set2; 3set2.insert(ivec.cbegin(), ivec.cend()); 4set2.insert({1, 3, 5, 7, 1, 3, 5, 7});
-
multimap
1multimap<string, string> authors; 2authors.insert({"Barth, John", "Sot-Weed Factor"}); 3authors.insert({"Barth, John", "Lost in the Funhouse"});
map的insert成员函数接受一个pair对象
1word_count.insert({word, 1}); // 最优 2word_count.insert(make_pair(word, 1)); 3word_count.insert(pair<string, size_t>(word, 1)); // 显式构造pair 4word_count.insert(map<string, size_t>::value_type(word, 1));
使用emplace成员函数添加元素
-
接受用以构造元素的参数: args用来构造元素
-
接受用以构造元素的参数和一个指示位置(指出从哪里开始搜索存储新元素的位置)
1c.emplace(args); 2 3c.emplace(p, args); 4// p作为一个提示, 指出从哪里开始搜索新元素应该存储的位置; 返回一个迭代器,指向具有给定关键字的元素 5 6// 函数函数一个pair,first是迭代器,指向具有指定关键字的元素,second是bool值,指示插入是否成功
map的emplace成员函数使用参数构造pair对象
1#include <iostream> 2#include <map> 3 4using namespace std; 5 6int main() 7{ 8 map<int, int> m{ {1, 1}, {0, 0} }; 9 m.emplace(3, 3); 10 auto elem = s.at(3); 11 cout << elem << endl; 12 13 return 0; 14}
输出
3
insert和emplace的返回类型依赖于容器类型和参数
允许关键字重复的关联容器: 返回指向新元素的迭代器
每次都会添加新元素
不允许关键字重复的关联容器 + 使用insert添加序列: 返回void
不允许关键字重复的关联容器 + 使用insert/emplace添加单个元素: 返回键值对
不允许关键字重复的关联容器: map,set,unordered_map,unordered_set
insert和emplace的返回类型为键值对 pair<iterator, bool>
键值对的second成员为布尔类型 bool
, 指示是否添加了新元素
second成员的值 | |
---|---|
true | 添加了新元素, first成员指向新元素 |
false | 未添加新元素, 关键字已存在; first成员指向具有给定关键字的元素 |
示例: 使用insert为map添加元素
1map<string, size_t> word_count; 2string word; 3while (cin >> word) 4{ 5 auto ret = word_count.insert({word, 1}); 6 7 // <=> 8 // pair<map<string, size_t>::iterator, bool> ret; 9 10 if (!ret.second) // 关键字已存在 11 ++ret.first->second; 12 13 // => 14 // ++((ret.first)->second); 15 // ret的second指示添加元素成功与否 16 // ret的first为指向map元素的迭代器; 元素(键值对)的second成员为单词的出现次数, 初始值为1 17 // 添加元素不成功, 增加计数 18}