zoukankan      html  css  js  c++  java
  • 【足迹C++primer】38、关联容器操作(2)

    版权声明:本文为博主原创文章。未经博主同意不得转载。

    https://blog.csdn.net/cutter_point/article/details/35244805

    关联容器操作(2)

    map的下标操作

    map的下标操作
    map和unordered_map容器提供了下标运算符合一个相应的at函数
    对于一个map使用下标操作,其行为与数组或vector上的下标操作非常不同样:
    使用一个不再容器中的keyword作为下标。会加入一个此keyword的元素到map中

    map和unordered_map的下标操作
    c[k] 返回keyword为k的元素。假设keywordk不再c中,加入一个keyword为k的元素,对其进行值初始化
    c.at(k) 訪问keyword为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的时候。保证能够得到序列中全部具有给定keyword的元素
    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返回迭代器可能指向一个具有给定keyword的元素。但也可能不指向。
    假设keyword不在容器中,则lower_bound会返回keyword的第一个安全插入点--不影响
    容器中元素顺序的插入位置

    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就可以。
    这个函数接受一个keyword。返回一个迭代器pair,第一个迭代器指向
    第一个和keyword匹配的元素,第二个指向和最后一个匹配的元素的后一个位置

    void fun5()
    {
        //authors和search_item的定义,和前面的程序一样
        //pos保存迭代器对,表示keyword匹配的元素范围
        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上的下标操作非常不同样:
    //使用一个不再容器中的keyword作为下标。会加入一个此keyword的元素到map中
    
    /*
    map和unordered_map的下标操作
    c[k] 返回keyword为k的元素。假设keywordk不再c中,加入一个keyword为k的元素,对其进行值初始化
    c.at(k) 訪问keyword为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的时候,保证能够得到序列中全部具有给定keyword的元素 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返回迭代器可能指向一个具有给定keyword的元素,但也可能不指向。

    假设keyword不在容器中。则lower_bound会返回keyword的第一个安全插入点--不影响 容器中元素顺序的插入位置 */ 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就可以。 这个函数接受一个keyword。返回一个迭代器pair。第一个迭代器指向 第一个和keyword匹配的元素,第二个指向和最后一个匹配的元素的后一个位置 */ void fun5() { //authors和search_item的定义,和前面的程序一样 //pos保存迭代器对。表示keyword匹配的元素范围 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:放假了。我预计最多把今天写完了,明天開始大概要停更了。大家不要停止学习哦。一起加油,一起努力。这本书我还是会看下去的,仅仅是博客可能更不了了。








  • 相关阅读:
    算法竞赛入门经典习题2-3 韩信点兵
    ios入门之c语言篇——基本函数——5——素数判断
    ios入门之c语言篇——基本函数——4——数值交换函数
    144. Binary Tree Preorder Traversal
    143. Reorder List
    142. Linked List Cycle II
    139. Word Break
    138. Copy List with Random Pointer
    137. Single Number II
    135. Candy
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/9973869.html
Copyright © 2011-2022 走看看