关联容器

关联容器和顺序容器的差别

关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器的位置顺序存储和访问元素


两种基本的关联容器的类型是map和set

map元素:键-值对的形式组织,键用于索引,值表示存储和读取的元素
set元素:  仅包含一个键,支持某个键是否存在的查询


pair类型

#include<utility>

pair类型提供的操作
pair<T1,T2> p1;   空的pair类型,两个元素分别是T1和T2类型
pair<T1,T2> p1(v1,v2);  first成员初始化为v1,second成员初始化为v2
make_pair(v1,v2)   以v1和v2值创建一个新的pair对象,元素类型分别是v1和v2
p1 < p2      遵循字典次序,p1.first < p2.first 或 !(p1.first < p2.first) && p1.second < p2.second,返回true
p1 == p2   pair对象的first和second成员依次相等,则两个对象相等
p.first    返回p中名为first的公有数据成员
p.second  返回p中名为second的公有数据成员


生成新的pair对象

pair<string,string>  next_auth;
string first,second;
while(cin>>first>>second){
       next_auth = make_pair(first,second);
}
next_auth = pair<string,string>(first,second)     //用pair的构造函数

pair<string,string>  next_auth;
while(cin>>next_auth.first>>next_auth.second){}


注意:

容器元素根据键的次序排列:在迭代遍历关联容器时,我们可以确保键的顺序访问元素,而与元素在容器中的存放位置完全无关。


map类型(键和值前后顺序

关联的本质在于元素的值与某个特定的键相关联

键类型的约束: 键不但是一个类型,而且还有一个相关的比较函数(键类型上定义严格的弱排序

实际应用中,键类型必须定义 < 操作符,而且该操作符应能"正确工作"。

map类定义的类型
map<K,V>::key_type 用做索引的键的类型
map<K,V>::mapped_type  键所关联的值的类型
map<K,V>::value_type       一个pair类型,first元素是const map<K,V>::key_type类型,second
是map<K,V>::mapped_type类型

注: 这些类型都是map容器额外定义的类型别名


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

map<string,int>::iterator map_it = word_count.begin();
map_it.first = "new"; //error
++map_it.second;  //ok

下标操作符编程意义

map<string,int>   word_cnt;
string   word;
while(cin>>word)
       ++word_cnt[word];
下标操作符返回一个mapped_type类型的值。

insert函数应用,统计单词数(迭代器类型具体表现形式是其所在类而定)

参考map迭代器解引用将产生pair类型的对象

map<string,int>  word_cnt;
string  word;
while(cin>>word){
       pair<map<string,int>::iterator,bool>  ret = word_cnt.insert(make_pair(word,1));
        if(!ret.second)
                 ++ret.first->second;
}

使用count检查map对象中某键是否存在和使用find的不同(map中的键是不相等的吗???)

int  occurs = 0;
if(word_cnt.count("foo"))
            occurs = word_cnt["foo"];

int occurs;
map<string,int>::iterator it = word.find("foo");
if(it->word_cnt.end())
     occurs = it->second;

set类型

基本和map的操作类型一样

单词排除范例

void restricted_wc(ifstream& remove_file,map<string,int>& word_cnt)
{
       set<string>  excluded;
       string       remove_word;
       while(remove_file>>remove_word)
            excluded.insert(remove_word);
        string      word;
        while(cin>>word)
            if(!excluded(word))
                 ++word_count[word];
}

multimap和multiset中查找元素

count函数和find函数配合使用,基于一个事实同一个键所关联的元素必然相邻存放。

string       search_item("Alien");
typedef  multimap<string,string>::size_type  sz_type;
sz_type   entries = authors.count(search_item);
multimap<string,string>::iterator iter = authors.find(search_item);
for(sz_type  cnt = 0; cnt != entries; ++cnt, ++iter)
     cout<<iter->second<<endl;


返回迭代器的关联容器的操作

typedef  multimap<string,string>::iterator  authors_it;
authors_it    beg = authors.lower_bound(search_item);
authors_it    end = authors.upper_bound(search_item);
while(beg != end){
          cout<<beg->second<<endl;
          ++beg;
}

equal_range函数

返回一个迭代器pair对象,first成员是m.lower_bound(k),second成员是m.upper_bound(k)。

pair<authors_it,authors_it> pos = authors.equal_range(search_item);
while(pos.first != pos.second){
          cout<<pos.first->second<<endl;
          ++pos.first;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值