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:放假了,我预计最多把今天写完了,明天開始大概要停更了,大家不要停止学习哦,一起加油,一起努力,这本书我还是会看下去的,仅仅是博客可能更不了了。








查看全文
  • 相关阅读:
    git ssh配置
    spring事务的传播行为
    springboot tomcat启动
    error while loading shared libraries: libstdc++.so.6: cannot open shared object file
    centos7安装nginx1
    linux jdk 配置
    NET CORE 3.1 UPLOAD
    vue table formrt datetime languer
    net core 3.1 swagger
    css
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10831076.html
  • Copyright © 2011-2022 走看看