map是什么
map的本质
关联式容器,属于模板类关联的本质在于元素值与某个特定的键相关联,而并非通过元素在数组的位置类获取 key - value
map的功能
自动建立key-value的一一对应的关系。
学生学号用int,姓名用int
map<int,string>mapStudent;
map头文件
#Include<map>,注意,STL头文件没有扩张名
map的插入(3种方式)
insert函数插入pair数据
//insert函数插入pair数据
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, "student_one"));
mapStudent.insert(pair<int, string>(2, "student_two"));
mapStudent.insert(pair<int, string>(3, "student_three"));
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
用insert插入value_type数据
//用insert插入value_type数据
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(map<int, string>::value_type (1,"student_one"));
mapStudent.insert(map<int, string>::value_type (2,"student_two"));
mapStudent.insert(map<int, string>::value_type (3,"student_three"));
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
map中用数组方式插入数据
//map中用数组方式插入数据
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main(){
map<int, string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[2] = "student_two";
mapStudent[3] = "student_three";
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
map插入的问题
用insert函数插入数据,key一样插不进去
用pair判断是否插进
//用pair判断是否插进
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main(){
map<int, string> mapStudent;
pair<map<int, string>::iterator, bool> insert_pair;
insert_pair = mapStudent.insert(pair<int,string>(1,"student_one"));
if(insert_pair.second == true){
cout<<"Insert Successfully"<<endl;
}
else{
cout<<"Insert Failure"<<endl;
}
insert_pair = mapStudent.insert(pair<int, string>(1, "student_two"));
if(insert_pair.second == true){
cout<<"Insert Successfully"<<endl;
}else{
cout<<"Insert Failure"<<endl;
}
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
//运行结果
Insert Successfully
Insert Failure
1 student_one
数据方式插入map覆盖原有的数据
//数据方式插入map覆盖原有的数据
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int,string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[1] = "student_two";
mapStudent[2] = "student_three";
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
map的遍历(前向迭代器、反向迭代器、数组)
反向迭代器
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main(){
map<int,string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[2] = "student_two";
mapStudent[3] = "student_three";
map<int, string>::reverse_iterator iter;
for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
//运行结果
3 student_three
2 student_two
1 student_one
map的查找(常用find和count两种方法)
count函数判断关键字是否出现
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[2] = "student_two";
mapStudent[3] = "student_three";
if (mapStudent.count(1)) {
cout << "Found " << endl;
}
else {
cout << "Do not found" << endl;
}
if (mapStudent.count(5)) {
cout << "Found " << endl;
}
else {
cout << "Do not found" << endl;
}
return 0;
}
find函数来定位数据的位置
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main(){
map<int,string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[2] = "student_two";
mapStudent[3] = "student_three";
map<int, string>::iterator iter=mapStudent.find(1);
if(iter != mapStudent.end()){
cout<<"Found, the value is "<<iter->second<<endl;
}else{
cout<<"Do not found"<<endl;
}
return 0;
}
map的删除
map.erase(k)
删除map中键为k的元素,并返回size_type类型的值以表示删除的元素个数。
map.erase§
从map中删除迭代器p所指向的元素。p必须指向map确实存在的元素,而且不能等于map.end()
map.erase(b,e)
从map中删除一段范围内的元素,b,e必须标记map中的一段有效范围。
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main(){
map<int, string> mapStudent;
mapStudent[1]="student_one";
mapStudent[2]="student_two";
mapStudent[3]="student_three";
mapStudent[4]="student_four";
map<int, string>::iterator iter=mapStudent.begin();
for(;iter!=mapStudent.end();){
if((*iter).second=="student_one"){
mapStudent.erase(iter++);
}
else{
++iter;
}
}
for(iter=mapStudent.begin();iter!=mapStudent.end();iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
运行结果
2 student_two
3 student_three
4 student_four
map排序
默认按照key从小到大排序
template<class Key, class T,class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T>>> class map;
其中比较熟悉是是Key和Value
看第3个参数
class Comapre = less<Key>
其中less 是一个函数对象,所谓函数对象,就是调用操作符的类,其对象被称为函数对象,它们是行为类似函数的对象。表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个类,其实质是对operator()操作符的重载
template<class T> struct less : binary_function<T,T,bool>
{
bool operator() (const T&x,const T&y)const
return x < y;
}
他是一个带模板的struct,仅仅对()运算进行了重载,实现很简单,用起来很方便,与less对应的还有greater
按照key从大到小排序 greater
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main(){
map<string, int, greater<string> > mapStudent;
mapStudent["LiMin"]=90;
mapStudent["ZiLinMi"]=72;
mapStudent["BoB"]=79;
map<string, int>::iterator iter=mapStudent.begin();
for(iter=mapStudent.begin();iter!=mapStudent.end();iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
重定义map内部中的Compare
#include <map>
#include <string>
#include <iostream>
using namespace std;
struct CmpByKeyLength {
bool operator()(const string& k1, const string& k2) {
return k1.length() < k2.length();
}
};
int main(){
map<string, int, CmpByKeyLength > mapStudent;
mapStudent["LiMin"]=90;
mapStudent["ZiLinMi"]=72;
mapStudent["BoB"]=79;
map<string, int>::iterator iter=mapStudent.begin();
for(iter=mapStudent.begin();iter!=mapStudent.end();iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
return 0;
}
key是结构体的map排序
#include <map>
#include <string>
#include <iostream>
using namespace std;
typedef struct tagStudentInfo
{
int iID;
string strName;
bool operator < (tagStudentInfo const& r) const {
//这个函数指定排序策略,按iID排序,如果iID相等的话,按strName排序
if(iID < r.iID) return true;
if(iID == r.iID) return strName.compare(r.strName) < 0;
return false;
}
}StudentInfo;//学生信息
int main(){
/*用学生信息映射分数*/
map<StudentInfo, int>mapStudent;
StudentInfo studentInfo;
studentInfo.iID = 1;
studentInfo.strName = "student_one";
mapStudent[studentInfo]=90;
studentInfo.iID = 2;
studentInfo.strName = "student_two";
mapStudent[studentInfo]=80;
map<StudentInfo, int>::iterator iter=mapStudent.begin();
for(;iter!=mapStudent.end();iter++){
cout<<iter->first.iID<<" "<<iter->first.strName<<" "<<iter->second<<endl;
}
return 0;
}
将map按value排序
先将map的元素按照pair形式插入vector中,在对vector进行排序
#include <map>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
typedef pair<string, int> PAIR;
bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {
return lhs.second < rhs.second;
}
struct CmpByValue {
bool operator()(const PAIR& lhs, const PAIR& rhs) {
return lhs.second < rhs.second;
}
};
int main(){
map<string, int> name_score_map;
name_score_map["LiMin"] = 90;
name_score_map["ZiLinMi"] = 79;
name_score_map["BoB"] = 92;
name_score_map.insert(make_pair("Bing",99));
name_score_map.insert(make_pair("Albert",86));
/*把map中元素转存到vector中*/
vector<PAIR> name_score_vec(name_score_map.begin(), name_score_map.end());
sort(name_score_vec.begin(), name_score_vec.end(), CmpByValue());
/*sort(name_score_vec.begin(), name_score_vec.end(), cmp_by_value);也是可以的*/
for (int i = 0; i != name_score_vec.size(); ++i) {
cout<<name_score_vec[i].first<<" "<<name_score_vec[i].second<<endl;
}
return 0;
}
map的原理
底层红黑树