c++primer第五版第十一章练习

来源:互联网 发布:手机屏幕画笔软件 编辑:程序博客网 时间:2024/05/18 00:12

11.1

map是关键字-值的储存,关键字是唯一的,通过下标运算符访问关键字对应的值,默认储存顺序是按照关键字

vector储存的是对象,通过下标运算符访问对应的对象,储存顺序按照添加顺序


11.2

list 用在需要频繁的插入或删除元素

vector 在需要索引访问时

deque 由于是先进先出,用在一些消息内容上

map 像字典之类的

set 用于检测是否含有


11.3

这个该了一下,变成统计字母

#include <iostream>#include <map>#include <set>#include <string>#include <fstream>int main(int argc, char **argv){using namespace std;ifstream ifile(argv[1]);if (!ifile){cerr << "open file error!";exit(1);}map<char, size_t> letter;//统计字母数量set<char> exclude{ ',', '<', '.', '>', '/', '?', ';', ':', '\'', '"', '[', '{', ']', '}', '\\', '|', '*', '-', '=', '+', '_', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')' };char temp;while (ifile >> temp){if(exclude.find(temp)==exclude.cend())<span style="white-space:pre"></span>++letter[temp];}for (auto x : letter)cout << x.first << "\t" << x.second << endl;return 0;}

11.4

#include <iostream>#include <map>#include <set>#include <string>#include <fstream>#include <cctype>int main(int argc, char **argv){using namespace std;ifstream ifile(argv[1]);if (!ifile){cerr << "open file error!";exit(1);}map<char, size_t> letter;set<char> exclude{ ',', '<', '.', '>', '/', '?', ';', ':', '\'', '"', '[', '{', ']', '}', '\\', '|', '*', '-', '=', '+', '_', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')' };char temp;while (ifile >> temp){if (exclude.find(temp) == exclude.end())//如果没有在其中找到tempor isalpha(temp); 当不是字母时返回0、小写2、大写1++letter[tolower(temp)];//把temp放进letter中,如果已存在则对应计数+1,否则先创建并让对应计数设置为1tolower返回小写}for (auto x : letter)cout << x.first << "\t" << x.second << endl;return 0;}

11.5

set的元素类型是关键字

map的元素类型是 关键字-值 组合

11.6

set是关联容器

list是顺序容器

关联容器不支持像push_back、push_front之类的操作,因为储存是按照关键字来储存的


11.7

#include <iostream>#include <vector>#include <map>#include <string>int main(){using namespace std;map<string, vector<string>> msv;string temp,t;cout << "enter Familys name:";cin >> temp;while (cin){while (cin){cout << "enter Family:";cin >> t;msv[temp].push_back(t);//下标为temp对应的vector把t添加进入容器}cin.clear();cout << "enter Familys name:";cin >> temp;}cin.clear();for (auto &x : msv){cout << x.first << ":" << endl;for (auto &a : x.second)//输出当前关键字对应的vector的内容cout << a << "\t";cout << endl;}system("pause");return 0;}

11.8

#include <iostream>#include <vector>#include <string>bool isnot(std::vector<std::string> &v,std::string &s);int main(){using namespace std;vector<string> word;string temp;while (cin >> temp){if (isnot(word, temp))word.push_back(temp);}for (auto &x : word)cout << x << "\t";system("pause");return 0;}bool isnot(std::vector<std::string> &v, std::string &s){for (auto &x : v){if (x == s)return false;}return true;}
set的关键字不允许重复,所以不用花费外的代码来检查


11.9

map<string,list<int>> m

#include <iostream>#include <fstream>#include <map>#include <list>#include <string>#include <set>#include <sstream>#include <cctype>#include <algorithm>int main(int argc, char **argv){using namespace std;ifstream ifile(argv[1]);if (!ifile){cerr << "open file error!";exit(1);}map<string, list<int>> msl;string word;string temp;int line=1;while (getline(ifile,word))//读取一行{istringstream iss(word);//关联到行while (iss >> temp)//读取字符串{if (ispunct(temp[temp.size() - 1]))//去除标点符号temp.erase(temp.size()-1,1);if (isupper(temp[0]))//转换为小写开头temp[0] = tolower(temp[0]);/*if (find(msl[temp].begin(), msl[temp].end(), line) == msl[temp].begin())msl[temp].push_back(line);*/bool b = true;for (auto x : msl[temp])//检查行号是否出现过(单词第一次在当前行号){if (x == line){b = false;break;}}if (b)msl[temp].push_back(line);}++line;}for (auto &x : msl){cout << x.first;if (x.first.size() <= 7)cout << "\t";cout << "\tin line: ";for (auto a : x.second)cout << a << "\t";cout << endl;}return 0;}

11.10

可以,因为有定义运算符"<"

11.11

using func=bool(const Sales_data &,const Sales_data &);

multiset<Sales_data,func*> bookstore(compareIsbn);


11.12

#include <iostream>#include <vector>#include <string>#include <utility>//pairint main(){using namespace std;vector<pair<string, int>> vpsi;string tstr;int tint;while (cin>>tstr>>tint){vpsi.push_back({ tstr, tint });//vpsi.push_back(pair<string, int>(tstr, tint));}for (auto &x : vpsi){cout << x.first << "\t" << x.second << endl;}system("pause");return 0;}

11.13

vec.push_back(pair<string,int>(str,i));

vec.push_back({str,i});

vec.push_back(make_pair(str,i));


vec.emplace_back(...↑...);

最好理解的是vec.push_back(pair<string,int>(str,i));,一眼就看到实参类型

最易于编写的是vec.push_back({str,i});,重复使用时不用大幅度变动代码


11.14

#include <iostream>#include <vector>#include <map>#include <string>#include <utility>//pairint main(){using namespace std;map<string, vector<pair<string,string>>> msv;string temp,n,b;cout << "enter Familys name:";cin >> temp;while (cin){while (cin){cout << "enter name and birth:";cin >> n >> b;msv[temp].push_back({ n, b });//为家庭temp添加新成员}cin.clear();cout << "enter Familys name:";cin >> temp;}cin.clear();for (auto &x : msv){cout << x.first << ":" << endl;for (auto &a : x.second)//输出当前关键字对应的vector的内容cout << a.first << "\t" << a.second << endl;cout << endl;}system("pause");return 0;}

11.15

mapped_type:vector<int>

key_type:int

value_type:pair<int,vector<int>>


11.16

cin>>map_it->second;


11.17

第二个非法,因为c对象是multiset类型,该类型没有push_back方法


11.18

map<string,int>::const_iterator iter=count_cbegin();


11.19

multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)> bookstore(isfun);multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)>::iterator iter = bookstore.begin();

11.20

本节的方法更易于阅读

#include <iostream>#include <map>#include <set>#include <string>#include <fstream>int main(int argc, char **argv){using namespace std;ifstream ifile(argv[1]);if (!ifile){cerr << "open file error!";exit(1);}map<char, size_t> letter;//统计字母数量set<char> exclude{ ',', '<', '.', '>', '/', '?', ';', ':', '\'', '"', '[', '{', ']', '}', '\\', '|', '*', '-', '=', '+', '_', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')' };char temp;while (ifile >> temp){auto iter = letter.insert({ temp, 1 });if (iter.second)++iter.first->second;}for (auto x : letter)cout << x.first << "\t" << x.second << endl;return 0;}

11.21

相当于++word_count[word];

++word_count.insert({word,0}).first.second;

调用insert会返回一个pair<iterator,bool>,iterator指向刚刚插入的元素,所以.first->second就是说刚刚插入的元素的值

所以就是把关键字word的值++


11.22

参数类型为:pair<string,vector<int>>

返回类型为:pair<map<string,vector<int>>::iterator,bool>


11.23

#include <iostream>#include <vector>#include <map>#include <string>int main(){using namespace std;map<string, multimap<string,string>> msv;string temp, f, l;cout << "enter Familys name:";cin >> temp;while (cin){while (cin){cout << "enter first last:";cin >> f >> l;if (!cin)//如果输入错误或输入结束,退出到输入家庭,否当输入结束符时,f和l依然会被赋值到msvbreak;msv[temp].insert({ f, l });}cin.clear();cout << "enter Familys name:";cin >> temp;}cin.clear();for (auto &x : msv){cout << x.first << ":" << endl;for (auto &a : x.second)cout << a.first << " " << a.second << endl;cout << endl;}system("pause");return 0;}

11.24

把关键字为0的值设为1,不存在就先创建然后设置


11.25

把第一个元素的值设为0


11.26

map的关键字

关键字对应的值

例如map<char,int> sel{{a,1},{b,2},{c,3},{d,5}};

sel[b]返回的就是2


11.27

需要统计同一关键字存在的数目时

需要确定关键字是否存在时


11.28

map<string,vector<int>>::iterator iter=m.find("***");

或者是auto iter=m.find("...");


11.29

upper_bound和lower_bount会指向同一个位置

equal_rabge返回一个pair<iter,iter>,pair的两个元素都指向一个相同的位置


11.30

因为pos是equal_range返回的一个pair对象,所以first是指向一个multimap,

所以意思是pos的第一个元素指向的multimap对象的第2个元素


11.31

#include <iostream>#include <string>#include <map>int main(){using namespace std;multimap<string, string> mss;string author,title;while (cin){cout << "enter author and title:";cin >> author>>title;if (!cin){cin.clear();break;}mss.insert({ author, title });}cout << "enter erase author and title:";author = title = "";cin.clear();cin >> author>>title;auto iter = mss.find(author);auto c = mss.count(author);/*while ((iter=mss.find(author)) != mss.cend()){if (iter->second == title)mss.erase(iter);}*/while (c){if (iter->second == title){mss.erase(iter);//删除书本,自动把iter指向下一个,无需++break;}++iter;--c;}for (auto &x : mss){cout << x.first << " " << x.second << endl;}system("pause");return 0;}

11.32

#include <iostream>#include <string>#include <map>#include <set>int main(){using namespace std;multimap<string, string> mss;string author, title;while (cin){cout << "enter author and title:";cin >> author >> title;if (!cin){cin.clear();break;}mss.insert({ author, title });}map<string, multiset<string>> msms;//multiset会排序for (auto &x : mss)msms[x.first].insert(x.second);for (auto &x : msms){for (auto &a : x.second)cout << x.first << "\t" << a << endl;}system("pause");return 0;}

11.33

#include <iostream>#include <fstream>#include <sstream>#include <set>#include <map>std::map<std::string, std::string> buildmap(std::ifstream &ifile)//初始化map{std::map<std::string, std::string> temp;std::string str,f,s;while (getline(ifile, str)){std::istringstream sst(str);sst >> f >> s;temp[f] = s;//把暗文对应的明文设置}return temp;}std::string trans(const std::string &s, std::map<std::string, std::string> &m)//转换{auto temp = m.find(s);if (temp != m.end())//如果是暗文return m[s];//返回暗文对应的明文elsereturn s;}int main(int argc,char **argv){using namespace std;ifstream ifpw(argv[1]), iftxt(argv[2]);if (!ifpw&&!iftxt){cerr << "open file error!\n";exit(1);}map<string, string> pw(buildmap(ifpw));//初始化密码文件string temp,f;while (getline(iftxt, temp)){istringstream iss(temp);while (iss >> f){cout << trans(f, pw) << " ";//输出f的明文(如果f是暗文)}cout << endl;}system("pause");return 0;}

或者书的:

#include <iostream>#include <string>#include <map>#include <fstream>#include <sstream>using namespace std;map<string, string> buildMap(ifstream &map_file){map<string, string> trans_map;string key, value;while (map_file >> key>>value){if (value.size() > 1)trans_map[key] = value.substr(1);elsethrow 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);if (map_it != m.cend())return map_it->second;elsereturn s;}void word_transform(ifstream &map_file, ifstream &input){auto trans_map = buildMap(map_file);string text;while (getline(input, text)){istringstream stream(text);string word;bool firstword = true;while (stream >> word){if (firstword)firstword = false;elsecout << " ";cout << transform(word, trans_map);}cout << endl;}}int main(int argc, char **argv){ifstream map_file(argv[1]), infile(argv[2]);if (!map_file || !infile){cerr << "open file error!\n";exit(1);}word_transform(map_file, infile);return 0;}

11.34

错误,transform的map形参是const 的,下标运算符返回的是引用


11.35

使用trans_map[key]时,当赋值出现重复的关键字时,该关键字对应的值为最后一关键字的值

使用insert时,当检查到trans_map里已经存在该关键字,则不进行插入,所以该关键字对应的值为第一次成功插入关键字时的值


11.36

当只有一个关键字和空格时,key会读取关键字,那么剩下的空格就交给的getline读取到了value中,因为value只有一个空格,所以size为1,if条件不成立,转交给else

所以会触发异常:throw runtime_error("no rule for "+key);


11.37

没有明显的排序、有时应用程序维护元素的顺序的代价是非常高昂的,这时使用无序会好一点

无序容器提供了与有序容器相同的操作,无序容器也允许有重复关键字的版本


11.38

#include <iostream>#include <string>#include <fstream>#include <unordered_map>#include <unordered_set>int main(int argc, char **argv){using namespace std;ifstream ifile(argv[1]);if (!ifile){cerr << "open file error!";exit(1);}unordered_map<char, size_t> letter;unordered_set<char> exclude{ ',', '<', '.', '>', '/', '?', ';', ':', '\'', '"', '[', '{', ']', '}', '\\', '|', '*', '-', '=', '+', '_', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')' };char temp;while (ifile >> temp){if (exclude.find(temp) == exclude.cend())++letter[temp];}for (auto x : letter)cout << x.first << "\t" << x.second << endl;return 0;}



#include <iostream>#include <string>#include <unordered_map>#include <fstream>#include <sstream>using namespace std;unordered_map<string, string> buildMap(ifstream &map_file){unordered_map<string, string> trans_map;string key, value;while (map_file >> key>>value){if (value.size() > 1)trans_map[key] = value.substr(1);elsethrow runtime_error("no rule for" + key);}return trans_map;}const string &transform(const string &s, const unordered_map<string, string> &m){auto map_it = m.find(s);if (map_it != m.cend())return map_it->second;elsereturn s;}void word_transform(ifstream &map_file, ifstream &input){auto trans_map = buildMap(map_file);string text;while (getline(input, text)){istringstream stream(text);string word;bool firstword = true;while (stream >> word){if (firstword)firstword = false;elsecout << " ";cout << transform(word, trans_map);}cout << endl;}}int main(int argc, char **argv){ifstream map_file(argv[1]), infile(argv[2]);if (!map_file || !infile){cerr << "open file error!\n";exit(1);}word_transform(map_file, infile);return 0;}





2015年11月25日20:24:35

以后在搞懂无序容器是什么鬼

今天以为亲人离世了,心情有点






0 0