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;
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容