关联迭代器

关联容器
两个基本的关联容器map和set
如果希望有效的存储不同值的集合,那么使用set容器比较合适,而map容器则更适用于需要存储(乃至修改)每个键所关联的值的情况。在做某种文本处理时,可使用set保存要忽略的单词,而字典则是map的一种很好的应用:单词本身是键,而他的解释说明是值


set和map类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素。如果一个键必须对用多个实例,则需使用multimap或multiset,这两种类型允许许多个元素拥有相同的键


map 关联数组:元素通过存储键来存储和读取
set 大小可变的集合,支持通过键实现的快速读取
multimap 支持同一个键多次出现的map类型
multiset 支持同一个键出项多次的set类型


utility文件中定义的pair类型


map<k,v>m 创建一个名为m的空map
map<k,v>m(m2)创建m2的副本,m和m2必须具有相同的键类型和值类型
map<k,v>m(b,e)创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本。元素的类型必须能转换为pair<const k,v>


使用map对象,则必须包含map头文件,在定义map对象时,必须指明键和关联值


在实际应用中,键类型必须定义<操作符,而且该操作符应能“正确地工作”,这一点很重要。
对于键类型,唯一的约束就是必须支持<操作符,至于时候支持其他的关系和相等运算,则不作要求。


map<K,V>::key_type在map容器中,用做索引的键的类型
map<K,V>::mapped_type在map容器中,键所关联的值的类型
map<K,V>::value_type一个pair类型,他的frist元素具有const map<K,V>::key_type类型,而second元素则为map<K,V>::mapped_type类型


在学习map的接口中,value_type是pair类型,它的值类型可


以改变,而键成员不能修改


map<string,int> word_count;
string word;
while(cin>>word)
++word_count;
简单记录每个单词出现的频率


insert(e)
insert(beg,end)
insert(iter,e)
word_count.insert(map<string,int>::value_type("abc",1);


word_count.insert(make_pair("abc",1));
或者使用
typedef map<string,int>::value_type valType;
word_count.insert(valType("abc",1);


重写单词统计程序
map<string,int> word_count;
string word;
while(cin>>word){
pair<map<string,int>::iterator,bool>ret = word_count.insert(make_pair(word,1));
if(!ret.second)
++ret.first->second;
}


map容器提供了两个操作:count 和find用于检查某个键是否存在而不会插入该键
m.count(k)
m.find(k)如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器


map容器的erase操作返回void,而顺序容器的erase操作返回一个迭代器,指向被删除元素后面的元素


erase(k)删除m中键为k的元素,返回size_type类型,表示删除的个数
erase(p)从m中删除迭代器p所指向的元素。p必须指向m中确实存在的元素,而且不能等于m.end()。返回void
erase(b,e)从m中删除一段范围内的元素,该范围由迭代器对b和e标记,b和e必须标记m中的一段有效fanwei:即b和e必须指向m中的一个元素或最后一个元素的下一个位置。而且,b和e要么相等。要么b所指向的元素必须出现在e所指向的元素之前。返回void类型


迭代器遍历
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;
}


在使用迭代器便利map容器时,迭代器指向的元素按键的升序排列


单词转换程序
int main(int argc,char **argv)
{
map<string,string>trans_map;
string key,value;
if(argc!=3)
throw runtime_error("wrong");
ifstream map_file;
if(!open_file(map_file,argv[1])
throw runtime_error("no");
while(map_file >> key >> value)
trans_map.insert(make_pair(key,value));


ifstream input;
if(!open_file,argv[2])
throw runtime_error("no");
string line;
while(getline(intput,line){
istringstream stream(line);
string word;
bool firstword = true;
while(stream >> word){
map<string,string>::const_iterator map_it=trans_map.find(word);
if(map_it != tran_map.end())
word = map_it->second;
if(firstword)
firstword = false;
else
cout<<" ";
cout <<word;
}
cout <<endl;
}
return 0 ;
}


set


set不支持下标操作,而且没有定义mapped_type类型。在set容器中,value_type不是pair类型,而是与key_type相同的类型。它们所指的都是set中存储的元素类型,这一差别也体现了set存储的元素仅仅是键,而没有锁关联的值。与map一样,set容器存储的键也必须是唯一的,而且不能修改。


与map容器操作一样,带有一个键参数的insert版本返回一个pair类型,带有迭代器类型参数的返回一个void类型


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


multimap和multiset类型
multimap不支持下标操作


带有一个键参数的erase版本将删除拥有该键的所有元素,并返回删除元素的个数,带有一个或一对迭代器参数的版本将返回void类型


使用find和count操作查找元素
string search_item("tian");
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;


m.lower_bound(k)返回一个迭代器,指向键不小于k的第一个元素
m.upper_bound(k)返回一个迭代器,指向键大于k的第一个元素
m.equal_range(k)返回一个迭代器的pair对象,他的first成员等价于lower_bound。他的second成员等价与upper_bound


lower_bound返回的迭代器不一定指向拥有特定键的元素。如果该键不在容器中,返回在保持顺序的前提下该键应被插入的第一个位置


typedef multimap<string,string>::iterator authors_it;
authors_it beg = authors.lower_bound(search_item),end = authors.upper_bound(search_item);


while(beg!=end){
cout<<beg->second<<endl;
++beg;
}


调用equal_range版本
typedef
multimap<string,string>::iterator 
authors_it;
pair<authors_it,authors_it> pos = authors.equal_range(search_item);
while(pos.first!=pos.end)
{
cout<<pos.first->second<<endl;
++pos.first;
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值