关联容器

来源:互联网 发布:乒乓球 知乎 编辑:程序博客网 时间:2024/06/07 19:14

关联容器支持通过键来高效地查找和读取元素。两个基本的类型的是map和set。map的元素以键-值(key-value)对的形式组织:键用作元素在map中的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效第支持是否存在的查询。这里写图片描述
一般来说,存储不同值的集合,使用set比较合适,map容器更适用于需要存储(修改)每个键所关联的值的情况。set和map类型的对象所包含的元素都具有不同的键,一个键对应一个值。一个键对应多个值则使用multiset和multimap类型。

1.pair类型

pair包含两个数据值,在创建pair对象时,必须提供两个类型名;
pair<string,string>anon;

关于pair的操作见下表:
这里写图片描述

2.map类型

map是键-值对的集合,map类型通常可理解为关联数组:键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联。而并非通过元素子啊数组中的位置来获取。
在使用关联容器时,他的键不但有一个类型,而且还有一个相关的比较函数。默认情况下,标准库使用键类型定义的<操作符来实现键的比较。
所用的比较函数必须在键类型上定义严格弱排序(strict weak ordering),所谓的严格弱排序可理解为键类型数据上的“小于”关系。对于键类型,唯一的约束就是必须支持<操作符。
map中定义了3种类型:key_type(键类型),mapped_type(值类型),value_type(pair类型,它的first元素具有const map< K,V>::key_type类型,second元素则为map< K,V>::mapped_type类型)。在学习map的接口时,要注意value_type是pair类型,它的值成员可以修改,但键成员不能

2.1map迭代器 进行解引用将产生pair类型的对象。

对迭代器进行解引用时,将获得一个引用,指向容器一个value_type类型的值。对于map容器,其value_type 就是pair值。

//get an iterator to an element  in word_countmap<string,int>::iterator map_it=word_count.begin();//*map_it is a reference to a pair<const string ,int>objectcout<<map_it->first;//prints the key for this elementcout<<""<<map_it->second;//prints the value for the element;map_it->first="new key";//error:key is const;++map_it->second;//ok

对迭代器进行解引用将获得一个pair对象,他的first成员存放key,为const,而second成员则存放值。

2.2使用下标访问map对象

使用下标访问map与使用下标访问数组或vector的行为不同:用下标访问不存在的元素将导致map容器中添加一个新的元素,他的键值为该下标值。 有别于vector和string类型,map下标操作符返回的类型与对map迭代器进行解引用获得的类型不同。
insert方法有多个重载函数,表明你插入的是一个pair,还是一对迭代器指明的若干个pair,还是插入一个pair到指定的位置,但通常使用的插入一个pair,这个函数最关键是它的返回值。这个返回值也是一个pair,pair的第一个元素是指向该map类型的迭代器,另一个是bool类型的变量,表明插入成功与否。可以用insert重写上面的程序:

int main(){    string str;    map<string,int> wordCount;    while(cin>>str)    {        //对于每个单词,都尝试去插入它        pair<map<string,int>::iterator,bool>ret = wordCount.insert(make_pair(str,1));        //通过检测返回值来判断插入是否成功        if(!ret.second)            //插入失败表明map中有这个单词,只需要把对应键的值自增即可            ++ret.first->second;    }    map<string,int>::iterator it_map = wordCount.begin();    cout<<"word"<<"\t\t"<<"count"<<endl;    for(;it_map != wordCount.end();++it_map)        cout<<it_map->first<<"\t\t"<<it_map->second<<endl;    return 0;}

我们可以通过count或者find函数来查找某个键是否存在。这两个函数的区别在于count返回的是出现的次数(对于map只能为0或者1),而find则返回的是指向该键的迭代器(如果没有找到,返回超末端迭代器:.end())。这意味着如果你是为为了统计是否存在,使用count就可以了,如果你找到某个元素并且还想使用它,那么find会比较合适。

    cout<<word.count("hello")<<endl;    cout<<word.count("nihao")<<endl;    map<string,int>::iterator it =word.find("no");           if (it!=word.end())           {               cout<<it->first<<endl;           }           else               cout<<"No find"<<endl;

从map中删除元素的erase操作有三种变化形式。
这里写图片描述
erase函数返回删除元素的个数,对于map容器,该值必然是0或1;如果返回0,则删除的元素在map中不存在。

map 对象的遍历

map<string,int>::const_iterator map_it=word_count.begin();while(map_it!=word_count.end()){    cout<<map_it->first<<"occurs"    <<map_it->second<<"times"<<endl;    ++map_it;}
0 0