关联容器操作(2)
map的下标操作
map的下标操作
map和unordered_map容器提供了下标运算符合一个对应的at函数
对于一个map使用下标操作,其行为与数组或vector上的下标操作很不相同:
使用一个不再容器中的关键字作为下标,会添加一个此关键字的元素到map中
map和unordered_map的下标操作
c[k] 返回关键字为k的元素,如果关键字k不再c中,添加一个关键字为k的元素,对其进行值初始化
c.at(k) 访问关键字为k的元素,带参数检测,如果k不再c重那么返回一个异常,out_of_range
与vector和string不同,map下标运算符返回的类型与解引用map迭代器得到的类型不同。
访问元素
如果我们关心的只不过是特定元素是否在容器中的时候,泛型算法find是最佳的选择
void fun1() { set<int> iset={0,1,2,3,4,5,6,7,8,9}; iset.find(1); //返回一个迭代器,指向key==1的元素 iset.find(11); //返回一个迭代器,值指向iset.end() iset.count(1); //返回1 iset.count(11); //返回0 }
今天上传的有点晚了,放假了,人也懒了- -
对map使用find代替下标操作
下标操作会自动添加元素,不好
void fun2() { map<string, size_t> word_count; string word; while(cin>>word) ++word_count[word]; if(word_count.find("foobar") == word_count.end()) cout<<"foobar is not in the map "<<endl; }
在multimap和multiset中查找元素
当我们遍历multimap和multiset的时候,保证可以得到序列中所有具有给定关键字的元素
void fun3() { multimap<string, string> authors; string search_item("Alain de Botton"); //要查找的作者 auto entries=authors.count(search_item); //元素的数量 auto iter=authors.find(search_item); //此作者的第一本书 //用一个循环查找此作者的所有著作 while(entries) { cout<<iter->second<<endl; //打印书名 ++iter; //指向下一个 --entries; //记录打印了多少书 } }
一种不同的,面向迭代器的解决方法
lower_bound返回迭代器可能指向一个具有给定关键字的元素,但也可能不指向。
如果关键字不在容器中,则lower_bound会返回关键字的第一个安全插入点--不影响
容器中元素顺序的插入位置
void fun4() { //authors和search_item的定义,和前面的程序一样 //beg和end表示对应此作者的元素的范围 multimap<string, string> authors; string search_item("Alain de Botton"); //要查找的作者 for(auto beg=authors.lower_bound(search_item), end=authors.upper_bound(search_item) ; beg != end; ++beg) cout<<beg->second<<endl; //打印每个题目 //upper_bound调用将end指向最后一个匹配search_item的元素的后一位 }
有木有发现,我现在博客越来越顺畅啦,相信大家也看看出来了吧,嘿嘿,我每次都打好底稿,然后再上传,边传边改,这样就不会像以前那样了,很乱,而且有点赶时间的嫌疑,
equal_range函数
不用lower_bound和upper_bound直接调用equal_range即可。
这个函数接受一个关键字,返回一个迭代器pair,第一个迭代器指向
第一个和关键字匹配的元素,第二个指向和最后一个匹配的元素的后一个位置
void fun5() { //authors和search_item的定义,和前面的程序一样 //pos保存迭代器对,表示关键字匹配的元素范围 multimap<string, string> authors; string search_item("Alain de Botton"); //要查找的作者 pair<multimap<string, string>::iterator, multimap<string, string>::iterator> pos; for(pos=authors.equal_range(search_item); pos.first != pos.second ; ++pos.first) cout<<pos.first->second<<endl; //打印每个题目 }
一个单词转换的map
施主,这次能看懂多少看个人造化了^_^。
单词转换文件,我把它叫做map_file.txt
brb be right back
k okay?
y why
r are
u you
pic picture
thk thanks!
18r later
我们希望转换的文本,这个叫做input.txt
where r u
y dont u send me a pic
k thk 18r
程序输出生成这样:
where are you
why dont you send me a picture
okay? thanks! later
#include<iostream> #include<fstream> #include<sstream> #include<map> #include<set> #include<string> #include<utility> //pair using namespace std; map<string, string> bulidMap(ifstream &map_file) { map<string, string> trans_map; //保存转换规则 string key; //要转换的单词 string value; //替换后的内容 //读取第一个单词存入key中,行中剩余内容存入value while(map_file>>key && getline(map_file, value)) { if(value.size() > 1) //坚持是否有转换规则 { value=value.substr(1); //跳过前导空格 //插入map trans_map.insert({key, value}); } else throw runtime_error(" no rule for "+key); } return trans_map; } const string & transform(const string &s, const map<string, string> &m) { //实际转换工作;此部分是程序核心 auto map_it=m.find(s); //如果单词在转换规则map中 if(map_it != m.cend()) { return map_it->second; //使用替换短语 } else { return s; //返回原值 } } void word_transform(ifstream &map_file, ifstream &input) { auto trans_map=bulidMap(map_file); //保存转换规则 string text; //保存输入中的没一行 while(getline(input, text)) //读取输入一行 { istringstream stream(text); //读取每个单词 string word; bool firstword=true; //控制是否打印空格 while(stream>>word) { if(firstword) firstword=false; else cout<<" "; //在单词之间打印一个空格 //transform返回它的第一个参数或其转换之后的形式 // cout<<endl<<"-------------------------------------"<<endl; // cout<<"这个单词是:"<<word<<endl; // cout<<"-------------------------------------"<<endl; cout<<transform(word, trans_map); //打印输出 } cout<<endl; //完成一行的转换 } } int main() { ifstream map_file,input; map_file.open("map_file.txt"); input.open("input.txt"); word_transform(map_file, input); map_file.close(); input.close(); return 0; }
好的劳动了一上午的成果!!!
/** * 功能:关联容器操作 * 时间:2014年6月27日09:55:55 * 作者:cutter_point */ #include<iostream> #include<fstream> #include<sstream> #include<map> #include<set> #include<string> #include<utility> //pair using namespace std; //map的下标操作 //map和unordered_map容器提供了下标运算符合一个对应的at函数 //对于一个map使用下标操作,其行为与数组或vector上的下标操作很不相同: //使用一个不再容器中的关键字作为下标,会添加一个此关键字的元素到map中 /* map和unordered_map的下标操作 c[k] 返回关键字为k的元素,如果关键字k不再c中,添加一个关键字为k的元素,对其进行值初始化 c.at(k) 访问关键字为k的元素,带参数检测,如果k不再c重那么返回一个异常,out_of_range */ //与vector和string不同,map下标运算符返回的类型与解引用map迭代器得到的类型不同。 //访问元素 //如果我们关心的只不过是特定元素是否在容器中的时候,find是最佳的选择 void fun1() { set<int> iset={0,1,2,3,4,5,6,7,8,9}; iset.find(1); //返回一个迭代器,指向key==1的元素 iset.find(11); //返回一个迭代器,值指向iset.end() iset.count(1); //返回1 iset.count(11); //返回0 } //对map使用find代替下标操作 //下标操作会自动添加元素,不好 void fun2() { map<string, size_t> word_count; string word; while(cin>>word) ++word_count[word]; if(word_count.find("foobar") == word_count.end()) cout<<"foobar is not in the map "<<endl; } //在multimap和multiset中查找元素 //当我们遍历multimap和multiset的时候,保证可以得到序列中所有具有给定关键字的元素 void fun3() { multimap<string, string> authors; string search_item("Alain de Botton"); //要查找的作者 auto entries=authors.count(search_item); //元素的数量 auto iter=authors.find(search_item); //此作者的第一本书 //用一个循环查找此作者的所有著作 while(entries) { cout<<iter->second<<endl; //打印书名 ++iter; //指向下一个 --entries; //记录打印了多少书 } } //一种不同的,面向迭代器的解决方法 /* lower_bound返回迭代器可能指向一个具有给定关键字的元素,但也可能不指向。 如果关键字不在容器中,则lower_bound会返回关键字的第一个安全插入点--不影响 容器中元素顺序的插入位置 */ void fun4() { //authors和search_item的定义,和前面的程序一样 //beg和end表示对应此作者的元素的范围 multimap<string, string> authors; string search_item("Alain de Botton"); //要查找的作者 for(auto beg=authors.lower_bound(search_item), end=authors.upper_bound(search_item) ; beg != end; ++beg) cout<<beg->second<<endl; //打印每个题目 //upper_bound调用将end指向最后一个匹配search_item的元素的后一位 } //equal_range函数 /* 不用lower_bound和upper_bound直接调用equal_range即可。 这个函数接受一个关键字,返回一个迭代器pair,第一个迭代器指向 第一个和关键字匹配的元素,第二个指向和最后一个匹配的元素的后一个位置 */ void fun5() { //authors和search_item的定义,和前面的程序一样 //pos保存迭代器对,表示关键字匹配的元素范围 multimap<string, string> authors; string search_item("Alain de Botton"); //要查找的作者 pair<multimap<string, string>::iterator, multimap<string, string>::iterator> pos; for(pos=authors.equal_range(search_item); pos.first != pos.second ; ++pos.first) cout<<pos.first->second<<endl; //打印每个题目 } //一个单词转换的map //施主,这次能看懂多少看个人造化了^_^。 /* 单词转换文件 brb be right back k okay? y why r are u you pic picture thk thanks! 18r later 我们希望转换的文本 where r u y dont u send me a pic k thk 18r 程序输出生成这样: where are you why dont you send me a picture okay? thanks! later */ map<string, string> bulidMap(ifstream &map_file) { map<string, string> trans_map; //保存转换规则 string key; //要转换的单词 string value; //替换后的内容 //读取第一个单词存入key中,行中剩余内容存入value while(map_file>>key && getline(map_file, value)) { if(value.size() > 1) //坚持是否有转换规则 { value=value.substr(1); //跳过前导空格 //插入map trans_map.insert({key, value}); } else throw runtime_error(" no rule for "+key); } return trans_map; } const string & transform(const string &s, const map<string, string> &m) { //实际转换工作;此部分是程序核心 auto map_it=m.find(s); //如果单词在转换规则map中 if(map_it != m.cend()) { return map_it->second; //使用替换短语 } else { return s; //返回原值 } } void word_transform(ifstream &map_file, ifstream &input) { auto trans_map=bulidMap(map_file); //保存转换规则 string text; //保存输入中的没一行 while(getline(input, text)) //读取输入一行 { istringstream stream(text); //读取每个单词 string word; bool firstword=true; //控制是否打印空格 while(stream>>word) { if(firstword) firstword=false; else cout<<" "; //在单词之间打印一个空格 //transform返回它的第一个参数或其转换之后的形式 // cout<<endl<<"-------------------------------------"<<endl; // cout<<"这个单词是:"<<word<<endl; // cout<<"-------------------------------------"<<endl; cout<<transform(word, trans_map); //打印输出 } cout<<endl; //完成一行的转换 } } int main() { ifstream map_file,input; map_file.open("map_file.txt"); input.open("input.txt"); word_transform(map_file, input); map_file.close(); input.close(); return 0; }
这个
bulidMap(ifstream &map_file)
里面的return记得要放到while循环的外面哦
我可是为了这个吃了不少苦头。
PS:放假了,我估计最多把今天写完了,明天开始大概要停更了,大家不要停止学习哦,一起加油,一起努力,这本书我还是会看下去的,只是博客可能更不了了。
【足迹C++primer】38、关联容器操作(2),布布扣,bubuko.com