chapter-11

// chapter-11.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<string>
#include<map>
#include<set>
#include<utility>           //定义了pair类型!
#include<vector>
#include<fstream>
#include<deque>

using namespace std;

class Info_Stu
{
public:
    Info_Stu() = default;
    Info_Stu(const string &a,const double b):id(a),grades(b){}
    string get_id()const { return id; }
    double get_grade()const { return grades; }

private:
    string id;
    double grades;
};

bool compare_info_stu(const Info_Stu &lh, const Info_Stu &rh)
{
    return lh.get_id() < rh.get_id();
}

map<string, string> bulid_map_format(ifstream &in_format)
{
    string tmp;
    map<string, string> ret;
    while (getline(in_format,tmp))
    {
        auto pos = tmp.find('=');
        if (pos!=string::npos)
        {
            string key_ret = tmp.substr(0, pos);
            ret[key_ret] = tmp.substr(pos+1, tmp.size() -pos-1);
        }
    }
    return ret;
}

int main()
{
    //按关键字有序保存元素
    //map                   关键字--值
    //set                   关键字,只保存关键字
    //multimap              关键字可重复
    //multiset              关键字可重复
    //无序集合
    //unordered_map         关键字无序储存,使用哈希函数储存元素
    //unordered_set         关键字无序储存,使用哈希函数储存元素
    //unordered_multimap    无序、可重复
    //unordered_multiset    无序、可重复

    //使用map做单词计数程序!
    map<string, size_t> word_count;         //数组下标通常定义为size_t
    string word;
    unsigned total=2;
    while (total>0)
    {
        if (cin >> word)
        {
            ++word_count[word];             //map下标运算符返回为左值,可以进行读写操作!
            --total;
        }
    }
    for (const auto &r : word_count)            //得到pair类型的对象!
    {
        cout << r.first << ":" << r.second <<" "<<((r.second>1)?"times":"time")<< endl;
    }
    cout << endl;

    //添加set过滤统计字符串
    set<string> exclude = { "the","and","but" };
    for (const auto &r : word_count)            //得到pair类型的对象!
    {
        if(exclude.cend()==exclude.find(r.first))
            cout << r.first << ":" << r.second << " " << ((r.second>1) ? "times" : "time") << endl;
    }

    //关联容器支持顺序容器基本操作(初始化、互换等等),但是不支持push_back等,因为关联容器是根据关键字储存的!
    //有序关联容器的关键字元素类型必须定义元素的比较方法,默认情况下使用<运算符来比较关键字!对于shared_ptr,则还需要定义删除器!
    set<Info_Stu, decltype(compare_info_stu)*> student_2017(compare_info_stu);

    //pair,可以通过first和second来访问成员!
    pair<string, size_t> word_the{ "the",3 };
    cout << word_the.first << ":" << word_the.second <<" "<<"times"<< endl;
    //pair<T1,T2> p(v1,v2)  /   pair<T1,T2> p={v1,v2}   /pair<T1,T2> p; 初始化形式!
    //make_pair(v1,v2)          返回一个pair
    //p.first和p.second          返回对应的成员
    //p1 < p2                   pair可以进行关系比较,其实质为first和second进行比较!
    //p1==p2                    pair可以进行XX比较,其是指为利用元素的==运算符实现!

    //关联容器操作
    //key_type                  此容器类型的关键字类型
    //mapped_type               每个关键字关联的类型:只适用于map
    //value_type                对于set,与key_type相同;对于map,为pair<const key_value,mapped_type>
    map<string, unsigned>::mapped_type val_1;
    //关联容器的迭代器,当解引用迭代器时,会得到value_type的值引用!
    //set的迭代器是const的,只能读取关键字,但是不能修改!map的关键字也不能修改!关联容器的关键字都不能修改!
    //通常不要对关联容器使用泛型算法,因为set和map的关键字均为const!
    //插入元素,set
    vector<int> ivec_insert_set = { 1,2,3,4,4,3,2,1 };
    set<int> iset_inserted;
    iset_inserted.insert(ivec_insert_set.cbegin(),ivec_insert_set.cend());
    iset_inserted.insert({ 1,2,3,4,5 });
    auto beg = iset_inserted.cbegin();
    for (; beg != iset_inserted.cend(); ++beg)
    {
        cout << *beg << " ";
    }
    cout << endl;
    //插入元素,map
    map<string, size_t> imap_inserted;
    imap_inserted.insert({ "and",6 });          //插入的元素必须为pair
    //c.insert(v)/c.emplace(args)/c.insert(b,e)/c.insert(il)/c.insert(p,v)/c.emplace(p.args)
    //insert的返回类型依赖于容器类型和参数,对于不包含重复关键字的容器,返回pair。first为迭代器,指向给定关键字的元素(map的元素为pair);second为布尔值,指出元素是否插入成功!(若给multiset和multimap插入元素,则只返回一个指向新元素的迭代器,因为插入肯定是成功的!)
    auto ret = imap_inserted.insert(make_pair("but", 9));
    cout << (ret.first->first) <<":"<< ret.second << endl;
    //删除元素
    //c.erase(k)            删除关键字为k的元素,返回删除元素的个数(size_t)
    //c.erase(p)            删除迭代器p指向的元素,返回p之后元素的迭代器
    //c.erase(b,e)          删除b到e中所有元素,返回e。
     //map的下标操作,只适用于非const的map和unordered_map!容器含有下标运算符和at函数!set不支持下标操作!
    cout << imap_inserted.at("and") << endl;        //当使用下标运算符[],若关键字k不存在,则添加关键字为k的元素!使用at函数,若关键字k不存在(带参数检查),则k不存在抛出异常!
    //访问元素
    //c.find(k)             返回指向关键字为k的元素迭代器,若k不在容器中,返回尾后迭代器
    //c.count(k)            统计关键字为k的元素的数量
    //c.lower_bound(k)      返回一个迭代器,指向第一个关键字不小于k的元素。lower_bound和upper_bound不适用于无序容器!
    //c.upper_bound(k)      返回一个迭代器,指向第一个关键字大于k的元素。若lower_bound和upper_bound返回相同的迭代器,则给定关键字不存在!
    //c.equal_range(k)      返回一个迭代器pair,指向关键字等于k的元素的范围!
    for (auto pos = imap_inserted.equal_range("but"); pos.first != pos.second; ++pos.first)
    {
        cout << pos.first->first << ":" << pos.first->second << " " << "times";
    }
    cout << endl;


    ifstream in_format("C:/Users/winack/Documents/Visual Studio 2017/Projects/chapter-11/format.txt");
    map<string, string> format_string;
    if (in_format)
    {
        format_string = bulid_map_format(in_format);
    }
    in_format.close();

    //map<string, string> format_string = { {"k","okay"},{"y","you"},{"r","are"} };
    deque<string> in_string;
    ifstream in_file("C:/Users/winack/Documents/Visual Studio 2017/Projects/chapter-11/1.txt");
    if(in_file)
    {
        
        string tmp;
        while (in_file>>tmp)
        {
            auto find_tmp = format_string.find(tmp);
            if (find_tmp != format_string.cend())
            {
                tmp = find_tmp->second;
            }
            in_string.push_back(tmp);
        }
    }
    in_file.close();
    for (auto &r : in_string)
    {
        cout << r << " ";
    }
    ofstream out_file("C:/Users/winack/Documents/Visual Studio 2017/Projects/chapter-11/2.txt");
    if (out_file)
    {
        for (auto &r : in_string)
        {
            out_file << r << " ";
        }
    }
    out_file.close();

    //无序容器,使用哈希函数和关键字类型==运算符,在关键字没有明显的序关系时维护元素的序列代价非常高昂时,无序容器很有用!
    //????????

    system("pause");
    return 0;
}

//关联容器的元素是按关键字来保存和访问的;顺序容器是按在容器中的位置顺序来保存和访问的!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容