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()) //如果没有在其中找到temp or isalpha(temp); 当不是字母时返回0、小写2、大写1
++letter[tolower(temp)]; //把temp放进letter中,如果已存在则对应计数+1,否则先创建并让对应计数设置为1 tolower返回小写
}
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> //pair
int 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> //pair
int 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依然会被赋值到msv
break;
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]; //返回暗文对应的明文
else
return 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);
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);
if (map_it != m.cend())
return map_it->second;
else
return 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;
else
cout << " ";
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);
else
throw 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;
else
return 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;
else
cout << " ";
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
以后在搞懂无序容器是什么鬼
今天以为亲人离世了,心情有点