关联容器和顺序容器的差别
关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器的位置顺序存储和访问元素
两种基本的关联容器的类型是map和set
map元素:键-值对的形式组织,键用于索引,值表示存储和读取的元素
set元素: 仅包含一个键,支持某个键是否存在的查询
pair类型
#include<utility>
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<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;
}