练习11.1:描述map和vector的不同
- map是关联容器,可以存放关键字-值,还能排序
- vector是顺序容器,能存放单一的数据,按照放进去的顺序
练习11.2:分别给出最适合使用list、vector、deque、map以及set的例子
- list 需要在中间进行很多的插入和删除操作。
- vector 不太需要插入和删除,需要快速查找
- deque 头尾删除和插入。需要快速查找
- map 字典
- set 黑名单
练习11.4:扩展你的程序,忽略大小写和标点。例如,“example.”也要递增相同的计数器
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int main()
{
std::map<std::string, size_t> word_count;
std::string word;
while (std::cin >> word)
{
transform(word.begin(), word.end(), word.begin(), ::tolower);//如果写了第7行,这里直接写tolower会报错,
word.erase(remove_if(word.begin(), word.end(), (int(*)(int))ispunct), word.end());//两个方法,具体在http://www.360doc.com/content/15/0825/17/14679766_494673239.shtml
++word_count[word];
}
for (const auto &i : word_count)
std::cout << i.first << " " << i.second << std::endl;
return 0;
}
练习11.5:解释map和set的区别。你如何选择使用哪个?
- map存放key,和value
- set只有key
练习11.7:定义一个map关键字是家庭的姓,值是一个vector,保存家中孩子们的名字。编写代码,实现添加新的家庭以及向已有家庭添加新的孩子
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
int main()
{
map<string, vector<string>> familychild = {
{"Joyce", {"James"}}
};
string firstName;
string childname;
while (cin >> firstName)
{
cin >> childname;
familychild[firstName].push_back(childname);
}
for (const auto &i : familychild)
{
cout << i.first << endl;
for (const auto &j : i.second)
cout << j << " ";
cout << endl;
}
return 0;
}
练习11.12:编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中
#include <iostream>
#include <utility>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<pair<string, int>> strInt;
string word;
int num;
pair<string, int> temp;
while (cin >> word)
{
cin >> num;
temp = make_pair(word, num);
strInt.push_back(temp);
}
for (auto &i : strInt)
{
cout << i.first << " " << i.second;
}
return 0;
}
练习11.14:扩展你在11.2.1节练习中编写的孩子姓到名的map,添加一个pair的vector,报错孩子的名和生日。
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int main()
{
map<string, vector<pair<string, string>>> familyName;
string name;
string fname;
string birthday;
cout << "Please enter second name" << endl;
while (cin >> name)
{
cout << "Please enter first name" << endl;
cin >> fname;
cout << "Please enter birthday" << endl;
cin >> birthday;
familyName[name].push_back(make_pair(fname, birthday));
cout << "Please enter second name" << endl;
}
for (auto &i : familyName)
{
for (auto &j : i.second)
cout << i.first << " "<< j.first << " " <<j.second << endl;
}
return 0;
}
练习11.15:对一个int到vector<int>的map,其mapped_type、key_type和value_type分别是什么?
- mapped_type是vector<int>
- key_type是int
- value_type是pair<int, vector<int>>
练习11.20:重写单词计数程序,使用insert代替下标
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
string word;
map<string, size_t> words;
while (cin >> word)
{
auto ret = words.insert({word, 1});
if (!ret.second)
{
++ret.first->second;
}
}
for (auto &i : words)
cout << i.second << " ";
return 0;
}
练习11.21:假定word_count是一个string到size_t的map,word是一个string,解释下面循环的作用
while (cin >> word)
++word_count.insert({word, 0}).first->second;
/*
这...我能说什么,牛逼大哥就是大哥
首先加入新的元素时:
执行插入,插入成功,然后用insert的返回执行后面的first最后找到元素自增,相当于第一次插入,并且元素是1
当存在时:
执行插入,发现存在了,但是依旧可以自增。
*/
练习 11.31:编写程序,定义一个作者以及其作品的multimap。使用find中一个元素并用erase删除它。确保你的程序在元素不在map中时也能正常运行,并且打印
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
multimap<string, string> authorBook = {
{"Tome", "C"},
{"Jerlu", "P"},
{"Zero", "H"},
{"Rong", "Hot active"},
{"Tome", "Hot action"}
};
string temp = "Tomde";
auto entries = authorBook.count(temp);
auto ret = authorBook.find(temp);
while (entries)
{
ret = authorBook.erase(ret);
--entries;
}
for (auto i : authorBook)
cout << i.first << " " << i.second << endl;
return 0;
}
练习11.35:在buildMap中,如果进行如下改写,会有什么效果?
trans_map[key] = value.substr(1)
改为trans_map.insert({key, value.substr(1)})
- 第一种:如果有重复的关键字会按照最后一个
- 改后:即使是重复的,也是用的是第一个
练习11.38:用unnordered_map重写单词计数程序与单词转换程序。
单词转换
#include <iostream>
#include <unordered_map>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
void word_transform(ifstream &map_file, ifstream &input);
unordered_map<string, string> bulidMap( ifstream &map_file);
const string &
transform(const string &s, const unordered_map<string, string> &m);
int main()
{
ifstream map_file("1.txt");
ifstream input("2.txt");
word_transform(map_file, input);
return 0;
}
void word_transform(ifstream &map_file, ifstream &input)
{
auto trans_map = bulidMap(map_file);
string line;
while (getline(input, line))
{
istringstream stream(line);
string word;
bool firstword = true;
while (stream >> word)
{
if (firstword)
firstword = false;
else
cout << " ";
cout << transform(word, trans_map);
}
cout << endl;
}
}
unordered_map<string, string> bulidMap( ifstream &map_file)
{
unordered_map<string, string> trans_map;
string key;
string value;
while (map_file >> key && getline(map_file, 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 ret = m.find(s);
if (ret != m.cend())
{
return ret->second;
}
else
return s;
}
单词计数
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main()
{
unordered_map<string, size_t> word_count;
string word;
while (cin >> word)
{
++word_count[word];
}
for (auto &i : word_count)
cout << i.first << " " << i.second << endl;
return 0;
}