zoukankan      html  css  js  c++  java
  • STL中Map和Set应用总结

    STL中的容器有顺序容器 (vector,list,deque),关联容器(map,set)还有一些其他容器。
    根据不同的场合选择不同的容器,会有意想不到的收获。


    Map是单词mapping(映射)的缩写
    Set是单词set(集合)的意思;


    Map和set内部的元素不可以重复,这一点不同于multimap和multiset。


    map 和 set使用相同的数据结构,不同的是 其中的Iterator的格式不一样,map使用pair这种配对的数据,并根据pair中第一个元素的值进行排序,而set的iterator并不具备天生的pair类型的元素,直接根据其中的元素进行排序,下面的伪码也许可以更清楚的表述:


    typedef template<class Key, class Value> rb_tree< pair<Key,Value> > map;

    typedef template<class T> rb_tree< T > set;



    map的节点是一对数据,set的节点是一个数据。


    map的形式 map<type1, type2> mymap;
    set的形式  set<type> myset;
     一般map是对有关联的事物存储,操作。  
      set是对一个字段进行存储,操作。


    map:使用关键字key来标示每一个成员,相当于字典,把一个值映射成另一个值,如果想创建字典的话,map就是一个很好的选择。map底层采用的是树型结构,多数使用平衡二叉树实现,查找某一值是常数时间,遍历起来效果也不错, 只是每次插入值的时候,会重新构成底层的平衡二叉树,效率有一定影响



    1. 声明方式:
        map<int, string> mapStudent;


    2. 数据的插入
    在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:
    第一种:用insert函数插入pair数据
        map<int, string> mapStudent;
        mapStudent.insert(pair<int, string>(1, "student_one"));
    第二种:用insert函数插入value_type数据
        map<int, string> mapStudent;
        mapStudent.insert(map<int, string>::value_type (1, "student_one"));
    第三种:用数组方式插入数据
        map<int, string> mapStudent;
        mapStudent[1] = "student_one";
        mapStudent[2] = "student_two";

    3. map的大小
    在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数:
        Int nSize = mapStudent.size();


    4. 数据的遍历
    第一种:应用前向迭代器
        map<int, string>::iterator iter;
        for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
            Cout<<iter->first<<"        "<<iter->second<<end;
    第二种:应用反相迭代器
        map<int, string>::reverse_iterator iter;
        for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
            Cout<<iter->first<<"        "<<iter->second<<end;
    第三种:用数组方式
        int nSize = mapStudent.size()
        for(int nIndex = 1; nIndex <= nSize; nIndex++) 
            Cout<<mapStudent[nIndex]<<end;

    5. 数据的查找(包括判定这个关键字是否在map中出现)
    这里给出三种数据查找方法
    第一种:用count函数来判定关键字是否出现,但是无法定位数据出现位置
    第二种:用find函数来定位数据出现位置它返回的一个迭代器,
    当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器
    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;
        iter = mapStudent.find(1);
        if(iter != mapStudent.end())
        {
            Cout<<"Find, the value is "<<iter->second<<endl;
        }
        Else
        {
            Cout<<"Do not Find"<<endl;
        }
    }


    第三种:这个方法用来判定数据是否出现
    Lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)
    Upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)
    例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3
    Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,程序说明
    mapPair = mapStudent.equal_range(2);
    if(mapPair.first == mapPair.second)
        cout<<"Do not Find"<<endl;


    6. 数据的清空与判空
    清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map

    7. 数据的删除
    这里要用到erase函数,它有三个重载了的函数
    迭代器删除 
        iter = mapStudent.find(1);
        mapStudent.erase(iter);
    用关键字删除
        Int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0
    用迭代器,成片的删除
        一下代码把整个map清空
        mapStudent.earse(mapStudent.begin(), mapStudent.end());
        //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合


    8. 其他一些函数用法
    这里有swap,key_comp,value_comp,get_allocator等函数,有兴趣的话可以自个研究



    set的基本使用:


    定义:
    定义一个元素为整数的集合a,可以用
    set<int> a;
    基本操作:
    对集合a中元素的有
    插入元素:a.insert(1);
    删除元素(如果存在):a.erase(1);
    判断元素是否属于集合:if (a.find(1) != a.end()) ...
    返回集合元素的个数:a.size()
    将集合清为空集:a.clear()
    集合的并,交和差
    set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
    set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
    set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
    (注意在此前要将c清为空集)。

    具体代码可以参考下面这个链接:http://blog.csdn.net/wu_lai_314/article/details/8439556

    注意:
    很重要的一点,为了实现集合的快速运算,set的实现采用了平衡二叉树,因此,set中的元素必须是可排序的。如果是自定义的类型,那在定义类型的同时必须给出运算符<的定义。



    收集资料时,在网络上转载了一个网友的一篇关于MAP和SET几个常见问题的博文,写的很好,相关链接如下:

    http://blog.csdn.net/wu_lai_314/article/details/8440550

    Do one thing at a time,and do well.
  • 相关阅读:
    ffmpeg rtmp推流 视频转码
    java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系
    nginx stream 流转发,可以转发rtmp、mysql访问流,转发rtmp、jdbc请求
    java web http 转https 通过nginx代理访问
    linux 服务器磁盘挂载
    novnc 通过websockify代理 配置多点访问
    linux 文件服务 minio 安装部署配置
    AOP实现原理,手写aop
    java 泛型
    JAVA反射getGenericSuperclass()用法
  • 原文地址:https://www.cnblogs.com/huiz/p/9610685.html
Copyright © 2011-2022 走看看