STL中基本的关联式容器有map和set,它们都是以红黑树作为其底层的结构,具有非常高的查找、删除效率,内容会按照键值自动排序。
使用map的注意事项:
1、关联式容器的键值是不允许修改的,所以永远不要试图去修改关联式容器的键值
2、插入数据时,如果使用的是insert,并且新插入的键值在原映射中已经存在,那么只是单纯的插入不成功,不会对原映射造成影响,如果使用[]进行插入操作,并且新插入的键值在原映射中已经存在,那么会将原映射中的实值改成要插入的实值。
3、insert插入操作会用到pair结构,pair结构在utility头文件中
4、查找数据时,如果使用find,并且要查找的键值不存在,那么不会对原集合造成影响,如果使用[]查找,并且要查找的值不存在,会建立一个新的实值为空,键值为要查找的元素到原映射中。
5、注意find返回值不是整数,而是一个迭代器,成功返回迭代器指向要查找的元素,失败返回的迭代器指向end
6、erase的返回值是整数,返回的是成功删除元素的个数,即成功返回1,失败返回0
7、map特有的两个操作:
upper_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数大的元素
lower_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数小的元素
1 #include<iostream> 2 #include<map> 3 #include<utility>//pair的头文件 4 #include<string> 5 using namespace std; 6 int main() 7 { 8 //**插入数据,特别注意使用insert时,如果已经存在要插入的键值,则插入操作相当于无效,而使用[]进行插入,如果已经存在要插入的键值, 9 //那么原来键值对应的内容将会被改写 10 //insert版本1: pair(iterator,bool) insert(const pair<key_type,value_type> &value); 11 //使用pair对进行插入,返回值是一个pair对,不过两个pair的内容不一样,要插入的pair中第一个是键值,第二个是实值, 12 //返回值中pair,第一个是一个map<key_type,value_type>的迭代器表示插入数据在容器中的位置,第二个是bool类型,插入成功返回1,否则返回0; 13 map<int,string> hash; 14 typedef pair<int,string> value; 15 typedef map<int,string>::iterator it; 16 typedef pair<it,bool> result; 17 result r1=hash.insert(map<int,string>::value_type(1,"abc")); 18 //注意由于之前存在键值3,所以这次插入是无效的 19 result r2=hash.insert(map<int,string>::value_type(1,"vvv")); 20 cout<<r1.first->first<<" "<<r1.first->second<<" "<<r1.second<<endl; 21 cout<<r2.first->first<<" "<<r2.first->second<<" "<<r2.second<<endl; 22 result r3=hash.insert(value(2,"ad"));//pair 23 cout<<r3.first->first<<" "<<r3.first->second<<" "<<r3.second<<endl; 24 //insert版本2 iterator insert(iterator pos,const pair<key_type,value_type> &value) 只返回插入元素在迭代器的位置 25 map<int,string>::iterator iter; 26 iter=hash.insert(hash.begin(),value(3,"vs")); 27 cout<<iter->first<<" "<<iter->second<<endl; 28 //注意由于之前存在键值3,所以这次插入是无效的 29 iter=hash.insert(hash.begin(),value(3,"vector")); 30 cout<<iter->first<<" "<<iter->second<<endl; 31 //insert 版本3 void insert(input_iterator start,input_iterator end) 32 //注意双迭代器组成的区间是前闭后开的就好了 33 map<int ,string> ha; 34 ha.insert(hash.begin(),hash.end()); 35 iter=ha.begin(); 36 for(;iter!=ha.end();iter++) 37 { 38 cout<<iter->first<<' '<<iter->second<<endl; 39 } 40 41 //[]直接插入数据,如果要插入的键值不存在,则插入一组新的映射,放回值是实值,如果存在要插入的键值,那么原来键值对应的数据会被改掉。 42 map<string,string> map_str; 43 map_str["hohai"]="100"; 44 cout<<map_str["hohai"]<<endl; 45 //注意这里插入了一个已有存在相同键值的数据,实际会将原来键值对应的实值改掉 46 map_str["hohai"]="hello"; 47 cout<<map_str["hohai"]<<endl; 48 49 50 //查找操作 51 //[]查找,从上面的例子中已经可以看到使用[]会返回一个实值的引用,可以利用这个进行查找,但是存在弊端,如果要查找的值不存在则会生成一个 52 cout<<map_str["aaa"]<<endl; 53 //find查找返回值是迭代器,成功则返回对应的迭代器,不成功返回的是end()迭代器 54 map<string,string>::iterator it_str; 55 it_str=map_str.find("hohai"); 56 if(it_str!=map_str.end()) 57 cout<<it_str->second<<endl; 58 else 59 cout<<"这个键值对应的元素不存在"<<endl; 60 61 it_str=map_str.find("hehe"); 62 if(it_str!=map_str.end()) 63 cout<<it_str->second<<endl; 64 else 65 cout<<"这个键值对应的元素不存在"<<endl; 66 67 //upper_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数大的元素 68 //lower_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数小的元素 69 //注意map是按照红黑树的结构进行存储的,添加元素的时候是会自动调整顺序的,所以这里的第一个指的是值最接近要查找的值,且比要查值稍大或者稍小的值 70 map<int,string> map_int; 71 map_int[60]="hello"; 72 map_int[30]="hi"; 73 map_int[100]="how are you"; 74 map<int,string>::iterator it_int; 75 it_int=map_int.upper_bound(25); 76 cout<<it_int->first<<" "<<it_int->second<<endl; 77 78 //遍历,如果键值比较有规律可以使用[]结合循环,否则使用迭代器 79 80 81 //删除数据 82 //map中erase有三个版本可以删除键值指定的数据,迭代器指定的数据和迭代器指定区间的数据 83 //其中使用键值删除的版本返回值是删除的个数(0或1),其他两个版本无返回值 84 cout<<map_int.erase(20)<<endl; 85 map<int,string>::iterator it_i=map_int.begin(); 86 for(;it_i!=map_int.end();it_i++) 87 { 88 cout<<it_i->first<<" "<<it_i->second<<endl; 89 } 90 cout<<map_int.erase(100)<<endl; 91 for(it_i=map_int.begin();it_i!=map_int.end();it_i++) 92 { 93 cout<<it_i->first<<" "<<it_i->second<<endl; 94 } 95 return 0; 96 }