一、访问元素
关联容器额外类型别名
key_type | 此容器类型的关键字类型 |
mapped_type | 每个关键字关联的类型,只 适用于map |
mapped_type | 对于set,与key_type相同 对于map,为pair<const key_type, mapped_type> |
二、关联容器迭代器
当解引用一个关联容器的迭代器时,我们会得到一个类型为容器的valued_type的值的引用。对map而言,value_type是一个pair类型,其first成员保存const的关键字,second成员保存值:
map<string, size_t> word_count auto map_it = word_count.begin(); // *map_it是指向一个pair<const string,size_t>对象的引用 cout << map_it->first; // 打印此元素的关键字 cout << " " << map_it->second; // 打印此元素的值 map_it->first = "new key"; // 错误:关键字是const 的 ++map_it->second; // 正确:我们可以通过迭代器改变元素
set的迭代器是const的
虽然set类型同时定义了iterator和const_iterator类型,但两种类型都只允许只读访问set中的元素。与不能改变一个map元素的关键字一样,一个set中的关键字也是const的,可以用一个set迭代器来读取元素的值,但不能修改:
set<int> iset = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; set<int>::iterator set_it = iset.begin(); if (set_it!=iset.end()) { *set_it=42; // 错误:set中的关键字是只读的 cout<<*set_it<<endl; // 正确:可以读关键字 }
遍历关联容器
map和set类型都支持begin和end操作。与往常一样,我们可以用这些函数获取迭代器,然后用迭代器类遍历容器。例如,我们可以编写一个循环程序来打印单词计数的结果,如下所示:
auto map_it=word_count.cbegin(); // 获取一个指向首元素的迭代器 while (map_it!=word_count.end()) // 比较当前迭代器和尾后迭代器 { cout << map_it->first <<" occurs " << map_it->second << " times" <<endl; // 解引用迭代器,打印关键字-值对 ++map_it; // 递增迭代器,移动到下一个元素 }
三、添加元素
对一个map进行insert操作时,必须记住元素类型是pair。通常,对于想要插入的数据,并没有一个现成的pair对象。可以在insert的参数列表中创建一个pair:
//向word_count插入word的4种方法 word_count.insert({word,1}); word_count.insert(make_pair(word,1)); word_count.insert(pair<string,size_t>(word,1)); word_count.inset(map<string,size_t>::value_type(word,1));
关联容器insert操作
c.insert(v) |
1. v是value_type类型的对象; |
c.insert(b,e) |
1. b和e是迭代器,表示一个c::value_type类型值的范围;il是这种值的花括号列表。 |
c.insert(p,v) | 1. 类似insert(v)但将迭代器p作为一个提示,指出从哪里开始搜索新元素应该存储的位置。返回一个迭代器,指向具有给定关键字的元素 |
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 6 int main() 7 { 8 map<string, size_t> word_count; 9 string word; 10 while (cin >> word) 11 { 12 auto ret = word_count.insert({ word, 1 }); // 13 if (!ret.second) 14 ++ret.first->second; 15 } 16 17 for (auto c : word_count) 18 cout << c.first << "出现了" << c.second << "次" << endl; 19 return 0; 20 }
运行结果:
四、删除元素
c.erase(k) | 从c中删除每个关键字为k的元素,返回一个size_type值,指出删除的元素的数量 |
c.erase(p) | 从c中删除迭代器p指定的元素,p必须指向c中一个真实元素,不能等于c.end().返回一个指向p之后元素的迭代器。若p指向c中的尾元素,则返回c.end() |
c.erase(b,e) | 删除迭代器对b和e所表示的范围中的元素,返回e |
五、map的下标操作
对一个map使用下标操作,其行为与数组或vector上的下标操作很不相同:使用一个不在容器中的关键字作为下标,会添加一个具有此关键字的元素到map中
map和unordered_map的下标操作
c[k] | 返回关键字为k的元素;如果k不做c中,添加一个关键字为k的元素,对其进行值初始化 |
c.at(k) | 访问关键字为k的元素,带参数检查;若k不在c中,抛出一个out_of_range异常 |
六、访问元素
在multimap和multiset中查找元素
第一方法:
1 #include <iostream> 2 #include <map> 3 #include <string> 4 #include <utility> 5 using namespace std; 6 7 int main() 8 { 9 multimap<string, string> author; 10 author.insert(make_pair("鲁迅", "朝花夕拾")); 11 author.insert(make_pair("鲁迅", "阿Q正传")); 12 author.insert(make_pair("鲁迅", "野草")); 13 author.insert(make_pair("罗贯中", "三国演义")); 14 author.insert(make_pair("罗贯中", "隋唐志传")); 15 author.insert(make_pair("琼瑶", "还珠格格")); 16 author.insert(make_pair("琼瑶", "情深深雨蒙蒙")); 17 18 string search_find("鲁迅"); 19 auto entries = author.count(search_find); 20 auto iter = author.find(search_find); 21 22 cout << search_find << "的作品集:" << endl; 23 while (entries) 24 { 25 cout << iter->second << endl; 26 ++iter; 27 --entries; 28 } 29 return 0; 30 }
运行结果:
第二种方法:
c.lower_bound(k) 返回一个迭代器,指向第一个关键字不小于k的元素 >=
c.upper_bound(k) 返回一个迭代器,指向第一个关键字大于k的元素 >
lower_bound返回的迭代器将指向第一个具有给关键字的元素,而upper_bound返回的迭代器则指向最后一个匹配关键字的元素之后的位置,如果元素不在multimap中,则 lower_bound 和 upper_bound会返回相等迭代器——指向一个不影响排序的关键字插入位置。
1 #include <utility> 2 using namespace std; 3 4 int main() 5 { 6 multimap<string, string> author; 7 author.insert(make_pair("鲁迅", "朝花夕拾")); 8 author.insert(make_pair("鲁迅", "阿Q正传")); 9 author.insert(make_pair("鲁迅", "野草")); 10 author.insert(make_pair("罗贯中", "三国演义")); 11 author.insert(make_pair("罗贯中", "隋唐志传")); 12 author.insert(make_pair("琼瑶", "还珠格格")); 13 author.insert(make_pair("琼瑶", "情深深雨蒙蒙")); 14 15 string search_find("鲁迅"); 16 cout << search_find << "的作品集:" << endl; 17 for (auto beg = author.lower_bound(search_find); beg != author.upper_bound(search_find); ++beg) 18 cout << beg->second << endl; 19 return 0; 20 }
运行结果:
第三种方法:
c.equal_range(k): 返回一个迭代器pair,表示关键字等于k的元素的范围,若k不存在,pair的两个成员均等于c.end()
1 #include <iostream> 2 #include <map> 3 #include <string> 4 #include <utility> 5 using namespace std; 6 7 int main() 8 { 9 multimap<string, string> author; 10 author.insert(make_pair("鲁迅", "朝花夕拾")); 11 author.insert(make_pair("鲁迅", "阿Q正传")); 12 author.insert(make_pair("鲁迅", "野草")); 13 author.insert(make_pair("罗贯中", "三国演义")); 14 author.insert(make_pair("罗贯中", "隋唐志传")); 15 author.insert(make_pair("琼瑶", "还珠格格")); 16 author.insert(make_pair("琼瑶", "情深深雨蒙蒙")); 17 18 string search_find("鲁迅"); 19 cout << search_find << "的作品集:" << endl; 20 for (auto pos = author.equal_range(search_find); pos.first != pos.second; ++pos.first) 21 cout << pos.first->second << endl; 22 return 0; 23 }
运行结果: