C++ map和set

    技术2022-07-10  126

    序列式容器与关联式容器

    C++容器分为序列式容器和关联式容器,序列式容器比如:vector list deque 等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构(顺序表),里面存储的是元素本身,这一点和关联式容器不同,关联式容器存储的是<key , value>结构的键值对,对数据的检索时比序列式容器效率更高。

    什么是键值对

    键值对是用来表示一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值value表示与key对应的信息

    SGI-STL中关于键值对的定义

    template <class T1, class T2> struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair(): first(T1()), second(T2()) {} pair(const T1& a, const T2& b): first(a), second(b) {} };

    first ---> key , second -->value

     

    树形结构的关联式容器:根据应用的场景不同,STL总共实现了两种不同结构的关联式容器:树型结构和哈希结构,树型结构的关联式容器主要有4中,map set multimap multiset。这四种容器的共同特点是:使用红黑树作为底层结构,容器中的元素是一有序的序列

    什么是map

    1.map是关联式容器,它按照特定的次序(按照key来比较)存储由键值key和 只value组合的元素

    2.在map中,键值key通常用于排序和唯一的标记元素,而值value中存储与此键值key关联的内容,键值key和value的类型可能奴同,并且map内部,key与value通过成员类型value_type绑定在一起,为其取别名为pair:

    typedef pair value_type;

    3.在内部,map元素总是按照键值key进行比较排序的。

    4.map支持下标访问符,在[]中放入key,就可以找到与之key对应的value

    5.map通常被实现为红黑树

    map 和 set

    map :存储元素的类型<key, value> , 要求key必须唯一

    set:存储元素的类型<key> , 要求key必须唯一

    multimap:存储元素的类型<key, value> , key可以重复

    multiset:存储元素的类型<key> , key可以重复

    底层数据结构都是相同的----红黑树,在存储元素时,默认会按照key升序的比较

    set的特性:可以进行去重 + 排序

    multiset的特性: 排序

    map模板参数列表:

    一般实例化时:Key T的类型,根据场景需要,可能还需要指定比较器的类型 ----- 比如:存储自定义类型的对象关于key的降序

     

    #include <iostream> using namespace std; #include <map> #include <string> //插入 void test2() { pair<string,string> array[3]; array[0].first = "orgin"; array[0].second = "橙子"; array[1].first = "apple"; array[1].second = "苹果"; array[2].first = "banan"; array[2].second = "香蕉"; map<string,string> m(array,array+sizeof(array)/ sizeof(array[0])); //m.insert("name","名字"); //调用pair构造函数创建一个匿名键值对象 m.insert(pair<string,string>("name","名字")); m.insert(pair<string,string>("man","男")); m.insert(pair<string,string>("names","名字s")); //make_pair是一个全局函数,输入两个参数将这两个参数打包成一个键值对返回 m.insert(make_pair("who","shui")); cout<<m.size()<<endl; for(auto& e: m) cout<<e.first<<"---"<<e.second<<endl; //插入失败:key不能重复,而apple已经存在 m.insert(make_pair("apple","苹果")); //通过key来获取与key对应的value // 注意: // 1.operator[]:底层调用insert,其具有插入元素的功能 // 2.operator[key]:返回对应的value,其具有查找的功能 // 原理: // 首先 将 <key , T> 构造成一个键值对,先map中进行insert // 如果key已经存在,插入失败,直接返回与key对应的value // 如果key不存在,插入成功,直接返回默认的value m.erase("apple"); m.erase(m.begin(),m.end()); } int main() { map<string,string> m; // 构造一个空的map pair<string,string> array[3]; array[0].first = "orgin"; array[0].second = "橙子"; array[1].first = "apple"; array[1].second = "苹果"; array[2].first = "banan"; array[2].second = "香蕉"; map<string,string> m2(array,array+sizeof(array)/ sizeof(array[0])); for(auto& e : m2) cout<<e.first<<"--------"<<e.second<<endl; cout<<endl; //采用迭代器遍历m2 auto it = m2.begin(); while(it!=m2.end()) { cout<<it->first<<"----"<<it->second<<endl; it++; } test2(); return 0; }

    map和multimap中的key是不能修改的,如果要修改,不能直接修改,可以将key删除然后重新插入

     

     

    multimap与map的区别:key的唯一性,multimap中没有operator[]

     

    set的重要功能:排序 + 去重

    multiset没有去重的功能,接口基本上与set的接口相同。

    实际上map、 multimap、 set 、multiset的基本使用都是相同的,只需要注意几点就ok

    1.map中的元素是键值对

    2.map中的key是唯一的,并且不能修改

    3.默认按照小于的方式对key进行排序

     

     

     

    Processed: 0.013, SQL: 9