C++primer第十章关联容器

map容器

map<string,vector< pair<string,int> >>::iterator itermap;

如若要取出pair中的数据,可以用vector< pair<string,int> >::iterator iter; iter->first

但是如果是map<string,vector< map<string,int> >> map1;vector< map<string,int> >::iterator iter;则不能用iter取,因为iter是指向vector的向量,也不能直接通过iter取,需要两层循环,首先取取map,然后利用map的迭代器取first即可。

分析:map没有first,map迭代器有,所以需要两个循环,一层用vector迭代器得到map,第二层用map的迭代器遍历元素,此时才有first

set容器

与map容器类似,只是set容器只有键值,并且二者的键值都是隐const类型

一、排序法则:

set和multiset都是定义在std空间里的类模板:

template<class _kTy, class _Pr less<_kTy> class _Allocation<_kTy> >class set

template<class _kTy, class _Pr less<_kTy> class _Allocation<_kTy> >class multiset

第二个参数用来定义排序准则,缺省准则less是一个仿函数,以operator<对元素进行比较。所谓排序准则,必须定义strict weak ordering.

和所有关联式容器类似,通常使用平衡二叉树完成。事实上,set和multiset通常以红黑树实作而成。自动排序的优点是使得搜寻元素时具有良好的性能,具有对数时间复杂度。但是造成的一个缺点就是:不能直接改变元素值。因为这样会打乱原有的顺序。改变元素值的方法是:先删除旧元素,再插入新元素。存取元素只能通过迭代器,从迭代器的角度看,元素值是常数。

平衡二叉检索树使用中序遍历算法,检索效率高于vector、deque和list等容器,另外使用中序遍历可将键值按照从小到大遍历出来。

b:自定义比较函数
    (1)元素不是结构体:
        例:
        //自定义比较函数myComp,重载“()”操作符
        struct myComp
        {
            bool operator()(const your_type &a,const your_type &b)
            [
                return a.data-b.data>0;
            }
        }
        set<int,myComp>s;
        ......
        set<int,myComp>::iterator it;
    (2)如果元素是结构体,可以直接将比较函数写在结构体内。
        例:
        struct Info
        {
            string name;
            float score;
            //重载“<”操作符,自定义排序规则
            bool operator < (const Info &a) const
            {
                //按score从大到小排列
                return a.score<score;
            }
        }
        set<Info> s;
        ......
        set<Info>::iterator it;

这种情况下,同一个型别可以运用不同的排序准则,而排序准则的初始值或状态也可以不同。如果执行期才获得排序准则,而且需要用到不同的排序准则,这种方式可以派上用场。

程序实例:

  template <class T>  class RuntimeCmp

{

    public:      enum cmp_mode{normal,reverse}; 

    private:      cmp_mode mode;  

    public:       RuntimeCmp(cmp_mode m = normal):mode(m){}        

    bool operator()( const T &t1,const T &t2)      

   {     

   return mode == normal ? t1 < t2 : t2 < t1;      

   }          

   bool operator==(const RuntimeCmp &rc)       

  {           

   return mode == rc.mode;       

   }  

}; 

 void fill(IntSet &set)  

 {       

set.insert(4);       

set.insert(7);       

set.insert(5);       

set.insert(1);       

set.insert(6);       

set.insert(2);      

 set.insert(5);  

}  

 typedef set<int,RuntimeCmp<int> > IntSet;     

 int main()  

{       

IntSet set1;      

fill(set1);       

PRINT_ELEMENTS(set1,"set1:");          

RuntimeCmp<int> reverse_order(RuntimeCmp<int>::reverse);          

IntSet set2(reverse_order);      

 fill(set2);       

PRINT_ELEMENTS(set2,"set2:");          

set1 = set2;

set1.insert(3);      

 PRINT_ELEMENTS(set1,"set1:");         

 if(set1.value_comp() == set2.value_comp())     

      cout << "set1 and set2 have the same sorting criterion" << endl;       

 else          

      cout << "set1 and set2 have the different sorting criterion" << endl;  

}     

运行结果

二、区别

注意:还有一个返回值不同的情况是:作用于序列式容器和关联式容器的erase()函数:

顺序容器的erase()函数:

 iterator erase(iterator pos); 

 iterator erase(iterator beg, iterator end);  

iterator erase(iterator pos);

iterator erase(iterator beg, iterator end);

 

关联式容器的erase()函数:

 void     erase(iterator pos);  

 void     erase(iterator beg, iterator end);  

 void erase(iterator pos);

 void erase(iterator beg, iterator end);

这完全是为了性能的考虑。因为关联式容器都是由二叉树实现,搜寻某元素并返回后继元素可能很费时。

三、函数区别

顺序容器.find(k):存在则返回迭代器,否则返回超出末端的迭代器;

顺序容器.find(b,e,k):存在返回迭代器,否则返回迭代器e。

map.find(k):如果map中存在按k索引的元素,则返回指向该元素的迭代器,否则返回超出末端的迭代器。

multimap.find(k):返回一个迭代器,指向第一个拥有正在查找的键的实例。

set.find(k):如果set中存在按k索引的元素,则返回指向该元素的迭代器,否则返回超出末端的迭代器。

 

顺序容器.insert(p,t):在迭代器p所指向的元素前面插入t元素,返回指向添加元素的迭代器;

顺序容器.insert(p,n,t):在迭代器p所指向的元素前面插入n个t元素,返回void;

顺序容器.insert(p,b,e):在迭代器p所指向的元素前面插入由迭代器b和e标记的范围内的元素,返回void类型.

map.insert(e):如果e.first已经存在,则保持map不变,返回一个pair对象,包含一个迭代器和一个bool值;

map.insert(b,e):返回void

map.insert(iter,e):如果e.first不存在,以iter为起点搜索,返回一个迭代器,指向m中具有给定键的元素;

set.insert(k):如果k参数是键,则返回pair类型对象,包含一个迭代器和一个bool值;

set.insert(b,e):如果k参数是迭代器对,则返回void类型.

 

顺序容器:只适用于vector和deque

map[m.first]:返回键所关联的值

set不支持下表操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值