// chapter-11.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include #include #include //定义了pair类型! #include #include #include 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 bulid_map_format(ifstream &in_format) { string tmp; map 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 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 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 student_2017(compare_info_stu); //pair,可以通过first和second来访问成员! pair word_the{ "the",3 }; cout << word_the.first << ":" << word_the.second <<" "<<"times"<< endl; //pair p(v1,v2) / pair p={v1,v2} /pair 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 map::mapped_type val_1; //关联容器的迭代器,当解引用迭代器时,会得到value_type的值引用! //set的迭代器是const的,只能读取关键字,但是不能修改!map的关键字也不能修改!关联容器的关键字都不能修改! //通常不要对关联容器使用泛型算法,因为set和map的关键字均为const! //插入元素,set vector ivec_insert_set = { 1,2,3,4,4,3,2,1 }; set 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 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 format_string; if (in_format) { format_string = bulid_map_format(in_format); } in_format.close(); //map format_string = { {"k","okay"},{"y","you"},{"r","are"} }; deque 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; } //关联容器的元素是按关键字来保存和访问的;顺序容器是按在容器中的位置顺序来保存和访问的!