目录
map和multimap
1. 定义和初始化
2. 插入数据元素操作
3. 赋值操作
4. 大小操作
5. 查找操作
6. 删除操作
7. 通过operator=修改元素
unorder_map 和 unorder_multimap
1. unordered_map的头文件
2. map和unordered_map的区别
map和multimap
map的底层实现原理是红黑树,使用容器map和multimap需要添加的头文件:
# include<map>
容器map和multimap的操作都一样,唯一的区别就是multimap中的数据元素可以重复。
1. 定义和初始化
// map<T1,T2> mapTT; // map默认构造函数
// map(const map& map); // 拷贝构造函数
2. 插入数据元素操作
- map.insert():向容器插入元素,返回pair<iterator, bool>;
- emplace():在当前map容器中的指定位置处构造新键值对,其效果和插入键值对一样,但是效率高;
- emplace_hint():本质上和emplace()在map容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数。
C++11新增的emplace()和emplace_hint()这两个插入元素的函数接口,效率比insert()好很多。
// map.insert(); // 向容器插入元素,返回pair<iterator, bool>
// map<int, string> serven_1;
第一种插入元素的方法(通过pair的方式插入对象)
// serven_1.insert(pair<int, string>(3,"文子"));
第二种插入元素的方法 (通过pair插入对象)
// serven_1.insert(make_pair(-1,"文子"));
第三种插入元素的方法 (通过value_type的方式插入对象)
// serven_1.insert(map<int, string::value_type(1,"文子")>);
第四种插入元素的方法 (通过数组的方式插入值)
// serven_1[3] = "三贝勒";
// serven_1[5] = "Serven";
emplace(); // 再当前map容器中的指定位置处构造新键值对,其效果和插入键值对一样,但是效率高
emplace_hint(); // 本质上和emplace()在map容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数
/* map的插入元素操作 */
serven_1.insert(pair<int, string>(0,"Serven"));
serven_1.insert(make_pair(1,"One"));
serven_1.insert(map<int, string>::value_type(2,"Two"));
serven_1.insert(map<int, string>::value_type(2,"Three")); // 相同的键值,编译能通过,但是运行后是没有添加这个的
serven_1[3] = "Four";
serven_1[4] = "Five";
map<int, string>::iterator map_it1;
map_it1 = serven_1.begin();
cout<<"serven_1的数据为:"<<endl;
while(map_it1 != serven_1.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
运行结果:
3. 赋值操作
- map& operator=(const map& mp):重载符号操作符;
- swap(mp):交换两个map容器。
// map& operator=(const map& mp); // 重载符号操作符
// swap(mp); // 交换两个map容器
/* map赋值操作 */
//operator=操作
serven_3 = serven_1;
cout<<"serven_3的数据为:"<<endl;
map_it1 = serven_3.begin();
while(map_it1 != serven_3.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
// swap交换操作
serven_1.swap(serven_2);
cout<<"serven_1的数据为:"<<endl;
map_it1 = serven_1.begin();
while(map_it1 != serven_1.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl;
cout<<"serven_2的数据为:"<<endl;
map_it1 = serven_2.begin();
while(map_it1 != serven_2.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
运行结果:
4. 大小操作
- size():返回容器中元素的数目;
- empty():判断容器是否为空;
- max_size():返回容器所能容纳键值对的最大个数,不同操作系统返回值不一样。
// size(); // 返回容器中元素的数目
// empty(); // 判断容器是否为空
// max_size(); // 返回容器所能容纳键值对的最大个数,不同操作系统返回值不一样
/* map的大小操作 */
cout<<"serven_1的大小为:"<<serven_1.size()<<endl;
cout<<"serven_2的大小为:"<<serven_2.size()<<endl;
cout<<"serven_1是否为空:"<<serven_1.empty()<<endl;
cout<<"serven_1在本台电脑windows操作系统上最大的容量为:"<<serven_1.max_size()<<endl;
cout<<endl<<endl;
运行结果:
5. 查找操作
- operator[]:map重载了[]运算符,只要知道map容器中某个键值对的键值,就可以向获取数组中元素那样,通过键直接获取对应的值;
- at(key):找到map容器中key键对应的值,如果找不到就会返回异常out_of_range;
- find(key):查找键为key是否存在,如果存在返回该键的元素的迭代器,不存在则返回map.end();
- count(val):返回容器中key为val的元素对组个数,对map来说,要么是0,要么是1,对multimap来说,可能是0,1,n;
- lower_bound(val):返回第一个key>=val元素的迭代器;
- upper_bound(val):返回第一个key>val元素的迭代器;
- equal_range(val):返回容器中key与val相等的上下限的两个迭代器,注意这是返回两个迭代器。
// operator[]; // map重载了[]运算符,只要知道map容器中某个键值对的键值,就可以向获取数组中元素那样,通过键直接获取对应的值
// at(key); // 找到map容器中key键对应的值,如果找不到就会返回异常out_of_range
// find(key); // 查找键为key是否存在,如果存在返回该键的元素的迭代器,不存在则返回map.end()
// count(val); // 返回容器中key为val的元素对组个数,对map来说,要么是0,要么是1,对multimap来说,可能是0,1,n
// lower_bound(val); // 返回第一个key>=val元素的迭代器
// upper_bound(val); // 返回第一个key>val元素的迭代器
// equal_range(val); // 返回容器中key与val相等的上下限的两个迭代器
/* map的查找操作*/
map<string, string> serven_str;
serven_str.insert(pair<string, string>("one","Ming"));
serven_str.insert(pair<string, string>("two","hong"));
serven_str.insert(pair<string, string>("three","fang"));
serven_str.insert(make_pair("four","cheng"));
serven_str.insert(map<string, string>::value_type("five","Ming"));
serven_str.insert(map<string, string>::value_type("four","wen"));
multimap<string, string> multi_serven_str;
multi_serven_str.insert(pair<string, string>("one","Ming"));
multi_serven_str.insert(pair<string, string>("two","hong"));
multi_serven_str.insert(pair<string, string>("three","fang"));
multi_serven_str.insert(make_pair("four","cheng"));
multi_serven_str.insert(map<string, string>::value_type("five","Ming"));
multi_serven_str.insert(map<string, string>::value_type("four","wen"));
cout<<"serven_str的数据为:"<<endl;
map<string, string>::iterator map_it_str;
map_it_str = serven_str.begin();
while(map_it_str != serven_str.end()){
cout<<"key = "<<map_it_str->first<<", value="<<map_it_str->second<<endl;
map_it_str++;
}
cout<<endl<<endl;
cout<<"multi_serven_str的数据为:"<<endl;
multimap<string, string>::iterator unmap_it_str;
unmap_it_str = multi_serven_str.begin();
while(unmap_it_str != multi_serven_str.end()){
cout<<"key = "<<unmap_it_str->first<<", value="<<unmap_it_str->second<<endl;
unmap_it_str++;
}
cout<<endl<<endl;
cout<<"serven_str的第三个元素的key = "<<serven_str.find("one")->first<<", serven_str的第三个元素的value = "<<serven_str.find("one")->second<<endl;
cout<<"serven_str中key为 one 的个数为:"<<serven_str.count("one")<<endl;
cout<<"serven_str中key为 six 的个数为:"<<serven_str.count("six")<<endl<<endl;
cout<<"multi_serven_str中key为 six 的个数为:"<<multi_serven_str.count("six")<<endl;
cout<<"multi_serven_str中key为 one 的个数为:"<<multi_serven_str.count("one")<<endl;
cout<<"multi_serven_str中key为 four 的个数为:"<<multi_serven_str.count("four")<<endl<<endl;
cout<<"serven_str中第一个key大于seven的迭代器的key = "<<serven_str.lower_bound("seven")->first<<", 值value = "<<serven_str.lower_bound("seven")->second<<endl;
cout<<"serven_str中第一个key小于apple的迭代器的key = "<<serven_str.upper_bound("fang")->first<<", 值value = "<<serven_str.upper_bound("fang")->second<<endl;
cout<<"serven_str中第一个key小于apple的迭代器的key = "<<serven_str.upper_bound("apple")->first<<", 值value = "<<serven_str.upper_bound("apple")->second<<endl; // 找不到的话就会指向begin()
pair<map<string, string>::iterator, map<string, string>::iterator> Two_it;
Two_it = serven_str.equal_range("four");
for(map<string, string>::iterator it = Two_it.first; it !=Two_it.second; it++){
cout << it->first << " => " << it->second << '\n';
}
运行结果:
6. 删除操作
- clear():删除所有元素;
- erase(pos):删除pos迭代器所指的元素,返回下一元素的迭代器;
- erase(begin, end):删除区间[begin, end)的所有元素,返回下一元素的迭代器;
- erase(val):删除容器中key为val的元素对组。
clear(); // 删除所有元素
erase(pos); // 删除pos迭代器所指的元素,返回下一元素的迭代器
erase(begin, end); // 删除区间[begin, end)的所有元素,返回下一元素的迭代器
erase(val); // 删除容器中key为val的元素对组
/* map的删除操作 */
cout<<"serven_2的数据为:"<<endl;
map_it1 = serven_2.begin();
while(map_it1 != serven_2.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
serven_2.erase(++serven_2.begin());
cout<<"删除第二个位置的元素后:"<<endl;
map_it1 = serven_2.begin();
while(map_it1 != serven_2.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
// 注意的就是,map的迭代不能 +=,因为底层存放的结构不是顺序的
serven_2.erase(++++serven_2.begin(), ++++++++serven_2.begin());
cout<<"删除第三个位置和第四个位置的元素后:"<<endl;
map_it1 = serven_2.begin();
while(map_it1 != serven_2.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
serven_2.erase(2);
cout<<"删除键为2的元素"<<endl;
map_it1 = serven_2.begin();
while(map_it1 != serven_2.end()){
cout<<"key = "<<map_it1->first<<", value="<<map_it1->second<<endl;
map_it1++;
}
cout<<endl<<endl;
运行结果:
7. 通过operator=修改元素
// 通过operator[]修改
cout<<"serven_str的数据为:"<<endl;
map_it_str = serven_str.begin();
while(map_it_str != serven_str.end()){
cout<<"key = "<<map_it_str->first<<", value="<<map_it_str->second<<endl;
map_it_str++;
}
cout<<endl<<endl;
serven_str["one"] = "servens";
cout<<"修改后serven_str的数据为:"<<endl;
map_it_str = serven_str.begin();
while(map_it_str != serven_str.end()){
cout<<"key = "<<map_it_str->first<<", value="<<map_it_str->second<<endl;
map_it_str++;
}
cout<<endl<<endl;
运行结果:
unorder_map 和 unorder_multimap
1. unordered_map的头文件
# include<unordered_map>
unordered_map的操作都跟map相似,没啥区别。
2. map和unordered_map的区别
map | unordered_map | |
有无序 | 有序 | 无序 |
底层数据结构 | 红黑树 | 哈希表 |
空间内存占用率 | 空间占用率高 | 占用内存高 |
执行效率 | 执行效率低 | 执行效率高 |
适用性 | 有顺序要求 | 查找频繁要求 |