关联容器的元素按关键字来保存和访问;顺序容器元素按在容器中的位置保存和访问
map multimap 头文件map 关键字-值对
set multiset 头文件set 关键字
无序容器 头文件unordered_map unordered_set
map使用
map<string,size_t>word_count;
string word;
while(cin>>word)
++word_count[word];
for(const auto &w:word_count)
cout<<w.first<<"occurs"<<w.second<<((w.second>1)?"times":"time")<<endl;
map<string,size_t>word_count;
set<string>exclude={"The","But","And","Or","An","A",
"the","but","and","or","an","a"};
string word;
while(cin>>word)
if(exclude.find(word)==exclude.end())//只统计不再exclude中的单词
++word_count[word];
//定义一个有20个元素的vector,保存0到9每个整数的两个拷贝
vector<int>ivec;
for(vector<int>::size_type i=0;i!=10;++i){
ivec.push_back(i);
ivec.push_back(i);
}
set<int>iset(ivec.cbegin(),ivec.cend());
multiset<int>miset(ivec.cbegin(),ivec.cend());
cout<<ivec.size()<<endl;//打印20
cout<<iset.size()<<endl;//打印10
cout<<miset.size()<<endl;//打印20
头文件utility
一个pair保存两个数据成员,pair是一个用来生成特定类型的模板
pair<类型,类型>对象:
pair<string,string>anon pair<string,vector<int>>line
pair的默认构造函数对数据成员进行值初始化,anon为包含两个空string的pair,line保存一个空string和一个空vector
初始化器:pair<string,string>author{"wmj","kobe"};
数据成员public,两个成员分别命名为first,second
pair<T1,T2>p; pair<T1,T2>p(v1,v2); pair<T1,T2>p={v1,v2}; make_pair(v1,v2)
关联器操作:
三种类型:
key_type 关键字类型 mapped_type关键字关联的类型,适用map
value_type set,与key_type一样;map,为pair<const key_type,mapped_type>
set<string>::key_type v1;
map<string,int>::value_type v2;
v1,v2类型?
map的value_type是一个pair类型,first成员const关键字,second成员保存值,故first的成员值不能改变
set关键字也是const
遍历关联容器:支持begin和end操作,获取迭代器遍历容器
添加元素
insert 添加一个元素或一个元素范围,map和set添加已存在元素对容器没有影响
insert两个版本:接受一对迭代器;接受一个初始化列表
vector<int>ivec={2,4,6,8,2,4,6,8};
set<int>set2;
set2.insert(ivec.cbegin(),ivec.cend());
set2.insert({1,3,5,7,1,3,5,7});
向map添加元素,添加pair
word_count.insert({word,1});
word_count.insert(make_pair(word,1));
word_count.insert(pair<string,size_t>(word,1));
word_count.insert(map<string,size_t>::value_type(word,1));
检测insert的返回值
返回pair,pair的first成员是一个迭代器,指向具有给定关键字的元素;second成员是bool,指向插入是否成功
auto ret=word_count.insert({word,1});
if(!ret.second)
++ret.first->second;
++ret.first->second; -> ++((ret.first)->second);
对于multimap,multiset添加元素,总会插入,因关键字不必唯一,返回一个指向新元素的迭代器。
删除元素erase
1.c.erase(k) k为关键字,返回size_type,指出删除元素的数量
2.c.erase(p) p为迭代器,指向c中的一个真实元素,不能等于c.end()。返回下一个迭代器
3.c.erase(b,e)删除迭代器对b和c所表示的范围中的元素,返回e
map的下标操作
针对对象:map和unordered_map 下标运算符,at函数
注意点:如果关键字不在map中,会为它创建一个元素并插入map,关联值将进行值初始化
c.at(k) 访问关键字为k的元素,带参数检查,若k不再c中,抛出out-of_range异常
下标操作的返回值
与其它下标运算符不同:
下标运算符返回的类型-> mapped_type
解引用map迭代器的类型->value_type
相同点:都返回左值,可读又可写
访问元素
1.c.find(k) 在则指向第一个关键字为k的元素,不在返回尾后迭代器
2.c.count(k)返回关键字为k的元素的数量
3.c.lower_bound(k)返回一个迭代器,指向第一个关键字不小于k的元素
4.c.upper_bound(k)返回一个迭代器指向第一个关键字大于k的元素
5.c.equal_range(k)返回迭代器pair,表示关键字等于k的元素的范围。若k不存在,pair的两个成员均等于c.end()
在multimap和multiset中查找元素
1)第一种
string search_item("wmj");
auto entries=authors.count(search_item);
auto iter=authors.find(search_item);
while(entries){
cout<<iter->second<<endl;
++iter;
--entries;
}
2)第二种
for(auto beg =authors.lower_bound(search_item),
end=authors.upper_bound(search_item);
beg!=end;++beg)
cout<<beg->second<<end;
//lower_bound的调用将beg定位到第一个与search_item匹配的元素,不存在指向第一个关键字大于search_item的元素,有可能是尾后迭代器。
如果没有元素与给定关键字匹配,返回迭代器指向给定关键字插入点,能保持容器中元素顺序的插入位置
3)第三种
for(auto pos=authors.equal_range(search_item);pos.first!=pos.second;++pos.first)
cout<<pos.first->second<<endl;
//equal_range返回迭代器pair