一、关联容器
关联容器通过键(key)存储和读取元素
1.1 pair类型
pair<string,int>anon;
anon=make_pair(string("aaa"),5);//不加STring(),vc6.0会报错
cout<<anon.first<<endl;//通过.first与.second访问元素
return 0;
2.2 map类型
a、加上#include<map>
使用下标访问map,返回键关联的值。
map<string,int>word_count;
word_count["we"]=5;
cout<<word_count["we"]<<endl;//5
b、map的键是key_type类型;
map的键关联的值是mapped_type;
整体是value_type,是一个pair类型。
map::insert操作(避免下标操作不必要的初始化)
c、插入元素类型使用pair类型键—值型。
word_count.insert(map<string,int>::value_type("you",1));
也可以用make_pair
word_count.insert(make_pair(string("they"),3)
d、检测insert返回值
带有一个键—值pair形参的insert版本将返回一个值:包含一个迭代器和bool值的对象,迭代器指向map中具有相应键的元素,bool为真则表示插入新元素。
map<int,int>word_count;
int a;
while(cin>>a)
{
pair<map<int,int>::iterator,bool>ret=word_count.insert(make_pair(a,1));
if(!ret.second)
++ret.first->second;// 可以看做:++((ret.first)->second)
}
cout<<word_count[1]<<endl;
e、查找读取map中元素
可以使用下标操作符,但不存在时会自动插入具有该键的新元素,赋值为0,这是一个危险
map<int,int>word_count;
int count=word_count[1];
使用count和find
map<int,int>word_count;
word_count.insert(make_pair(1,2));
int count;
map<int,int>::iterator it=word_count.find(1);
if(it!=word_count.end())
count=it->second;
map<int,int>word_count;
word_count.insert(make_pair(1,2));
int count=word_count.count(1);//对于map,count返回值只可能为0或1
f、map的遍历
map<int,int>word_count;
word_count.insert(make_pair(1,2));
word_count.insert(make_pair(3,4));
word_count.insert(make_pair(5,7));
map<int,int>::iterator it=word_count.begin();
while(it!=word_count.end())
{
cout<<it->first<<" "<<it->second<<endl;
++it;
}
return 0;
3.3 set类型
只是键的集合,没有值。
#include<set>
a、set的初始化
vector<int>vec;
for(int i=0;i<10;i++)
{
vec.push_back(i);
vec.push_back(i);
}
set<int>iset(vec.begin(),vec.end());
cout<<vec.size()<<" "<<iset.size()<<endl;//20 10(set中每个键只能对应一个元素)
return 0;
b、在set中插入元素
set<int>iset;
iset.insert(1);
b、获取元素
iset.find(1);//返回指向1的迭代器
iset.count(1);//返回1出现的次数(0或者1)
二、泛型算法
#include<algorithm>
a、find()
vector<int>vec;
for(int i=0;i<10;i++)
{
vec.push_back(i);
}
int value=10;
vector<int>::iterator it=find(vec.begin(),vec.end(),value);
cout<<"the value "<<value<<(it==vec.end()?" is not found":" is present")<<endl;
b、accumulate
#include<numeric>
char vec[]={'a','b','c'};
string sum=accumulate(vec,vec+3,string("") );
cout<<sum<<endl;//abc
c、fill
vector<int>vec(10);
fill(vec.begin(),vec.end(),9);
d、fill_n
vector<int>vec;//空的
fill_n(vec.begin(),10,9);//运行出错
引入back_inserter(插入迭代器)
vector<int>vec;//空的
fill_n(back_inserter(vec),10,9);//back_inserter生成插入迭代器,效果相当于在vec上调用push_back
e、对容器元素重新排序的算法
sort、unique、erase
vector<string>vec;//空的
vec.push_back("the");
vec.push_back("red");
vec.push_back("quick");
vec.push_back("fox");
vec.push_back("the");
vec.push_back("turtle");
sort(vec.begin(),vec.end());//用小于(<)操作符比较元素
for(int i=0;i<vec.size();i++)
{
cout<<vec[i]<<" ";
}
cout<<endl;
vector<string>::iterator it=unique(vec.begin(),vec.end());//unique()删除相邻重复元素,返回最后一个不重复元素后一个的迭代器;等于是把重复元素挤到最后面
vec.erase(it,vec.end());//删除后面的重复元素
for(int j=0;j<vec.size();j++)
{
cout<<vec[j]<<" ";
}
cout<<endl;
输出结果:
继续,如何统计这些词中长度大于等于6的词的个数?
先定义两个谓词函数(用于检测的函数,返回用于条件判断的类型,指出条件是否成立)
bool isShorter(const string&s1,const string&s2)
{
return s1.size()<s2.size();
}
bool GT6(const string &s)
{
return s.size()>=6;
}
调用函数:stable_sort()和count_if();
stable_sort(vec.begin(),vec.end(),isShorter);//按长度排序,相同长度字典序列不变
int wc=count_if(vec.begin(),vec.end(),GT6);//返回大于6的个数
f、再谈迭代器
#include<iterator>
(1)插入迭代器
包括:back_inserter(创建使用push_back实现插入的迭代器
front_inserter,使用push_front实现插入(vector不支持)
inserter,使用insert实现插入(在指定位置)
list<int>a,b,c;
int i;
for(i=0;i<4;i++)
a.push_front(i);//a:3 2 1 0
copy(a.begin(),a.end(),front_inserter(b)); //b:0 1 2 3
copy(a.begin(),a.end(),inserter(c,c.begin()));//c:3 2 1 0 c.begin()位置是固定的
(2)反向迭代器
list<int>a;
int i;
for(i=0;i<4;i++)
a.push_back(i);//0 1 2 3
list<int>::reverse_iterator it;
for(it=a.rbegin();it!=a.rend();it++)
cout<<*it<<" "; 3 2 1 0
可以以此实现反向排序
sort(a.rbegin(),a.rend());
假设有一个字符串对象,存储以逗号分隔的单词表,如何输出第一个和最后一个单词?
string a("we,you");
string::iterator it=find(a.begin(),a.end(),',');//用string做it 的作用域
cout<<string(a.begin(),it)<<endl;
string::reverse_iterator comma=find(a.rbegin(),a.rend(),',');
cout<<string(comma.base(),a.end());//.base将反向迭代器转化为正向,这样的写法保证单词不是倒序
cout<<endl;
(3)五种迭代器
输入、输出、前向、双向、随机访问迭代器