关联容器--map和set

map是关键字-值对的集合。关键字起到了索引作用,值则表示与索引相关的数据。set则只是关键字的集合,支持高效的关键字查询操作。使用map的实例程序如下:

    map<string,std::size_t> word_count;//定义一个string到size_t的map 
    set<string> exclude={"the","but","and","or","an","a"};//定义忽略统计的单词的set 
    string word;
    while(cin>>word)
    {
        if(exclude.find(word)==exclude.end())//如果统计的单词不再set当中 
            ++word_count[word];//统计单词的次数加1 
    }
    for(const auto &w:word_count)
        cout<<w.first<<" occurs"<<w.second<<((w.second)>1?" times":" time")<<endl;

对于map和set,其关键字必须是唯一的,但是multimap或multiset则允许多个元素具有相同的关键字。实例程序如下:

     vector<int> ivec; 
     for(vector<int>::size_type i=0;i!=10;++i)//ivec保存重复的1~10 
     {
        ivec.push_back(i);
        ivec.push_back(i);
     }
     set<int> iset(ivec.begin(),ivec.end());//将ivec初始化set 
     std::multiset<int> miset(ivec.begin(),ivec.end());//将ivec初始化multiset 
     cout<<ivec.size()<<endl;//20 
     cout<<iset.size()<<endl;//10
     cout<<miset.size()<<endl;//20
     //证明了容器set的关键字是唯一的,不可重复的。而multiset关键字可以重复。 

使用map和set的时候,其关键字类型必须是定义了严格弱序的,即定义了“<”函数,如果未定义,则可以为关键字类型定义一个比较函数。程序如下:

    class A//类型A没有定义<函数 
     {
        public:
            int v;
     }
     bool cmp(A a1,A a2)//定义外部函数< 
     {
        return a1.v<a2.v;
     }
     multiset<A,decltype(cmp)*> st(cmp);//使用自定义操作定义set 
     //定义multiset必须提供两个类型,关键字类型和比较操作类型(函数指针类型);

pair标准库类型定义子啊utility头文件中,一个pair保存两个数据成员。pair 的默认构造函数对数据成员进行值初始化。pair的操作如下:

这里写图片描述

     //默认初始化 
     pair<string,int> val1;
     cout<<val1.first<<" "<<val1.second<<endl;//"" 0

     pair<string,int> val2={"a",3};//列表初始化 
     cout<<val2.first<<" "<<val2.second<<endl;//"a" 1

     pair<string,int>val3=std::make_pair("c",2);//make_pair创建pair 
     cout<<val3.first<<" "<<val3.second<<endl;//"c", 2

     cout<<(val2>val3)<<endl;// 0

关联容器的额外类型别名:

这里写图片描述

这里写图片描述

一个map的value_type是一个pair,我们可以改变pair的值,但不能改变关键字成员的值,因其为const类型。而set迭代器是const的,故set的元素是只读的。


遍历关联容器支持像vector一样使用begin和end操作,获取迭代器来遍历容器。程序如下:


    map<string,std::size_t> word_count={{"hello",1},{"apple",2},{"world",3}};//定义一个string到size_t的map
    auto map_it=word_count.cbegin();
    while(map_it!=word_count.cend())
    {
        cout<<map_it->first<<" occurs "<<map_it->second<<((map_it->second)>1?" times":" time")<<endl;
        ++map_it;
    } 

向map添加元素有四种方法,如下代码。

/**向map插入元素的四种方法**/
map.insert({key,value});
map.insert(make_pair(key,value));
map.insert(pair<key,vaule>(key,vaule));
map.insert(map<key,vaule>::value_type(key,value));

insert操作返回的是一个pair,它的first成员时一个迭代器,指向具有给定关键字的元素,second成员是一个bool值,指出元素是否插入成功还是已经存在于容器中。

map<string,size_t> word_count;//定义一个string到size_t的空map
string word;
while(cin>.word)//输入单词
    auto ret=word_count.insert({word,1});//插入单词到map,返回一个pair
    if(!ret.second)//ret的second表示插入是否成功
        ++ret.first->second;//ret的first是一个元素的map,map->second是相应关键字的值。

关联容器提供了一个额外的erase操作,它接受一个key_type参数,删除匹配给定关键字的所有元素,返回实际删除的元素的数量。对于保存不重复关键字的容器,erase的返回值总是0或1。对于允许重复关键字的容器,删除的元素数量大于1.

if(map.erase(key_type))
    // process 1
else
    // process 2

map支持下标操作,其接受一个索引(关键字),获取与此关键字相关联的值。但是值得注意的是,如果关键字并不在map中,其会它创建一个元素并插入到map中,关联值会进行值初始化。当对于一个map进行下标操作时,会获得一个mapped_type对象,而当解引用一个map迭代器时,会得到一个value_type对象。

map<string,size_t> word_count;
word_count["apple"]=1;
//插入一个关键字为apple的元素,关联值进行值初始化(0),然后将1赋予个它。
cout<<word_count["apple"];//打印1

在关联容器中查找指定元素有如下操作:

c.find(k) : 返回key==k 迭代器

c.count(k) : 返回key==k的元素的数量

c.lower_bound(k) : 返回第一个key>=k的元素

c.upper_bound(k) : 返回第一个key>k的元素。

c.euqal_range(k) : 返回一个迭代器pair, 它的first成员等于c.lower_bound(k) ,second成员等于c.upper_bound(k)。

    map<string,size_t> mp={{"a",1},{"b",2},{"c",3},{"d",8}};
    auto it1=mp.find("a");//map<string,size_t>::iterator
    cout<<it1->second<<endl;//1

    int it2=mp.count("d");//map<string,size_t>::iterator
    cout<<it2<<endl;//1

    auto it3=mp.lower_bound("b");//map<string,size_t>::iterator
    cout<<it3->second<<endl;//2

    auto it4=mp.upper_bound("a");//map<string,size_t>::iterator
    cout<<it4->second<<endl;//2

    //pair<map<string,size_t>::iterator,map<string,size_t>::iterator> 
    autoit5=mp.equal_range("c");
    cout<<it5.first->second<<endl;//3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值