11.1
map是关联式容器,元素式按关键字保存和访问的;
vector是顺序容器,其元素是按照它在容器中的位置来保存和访问的;
11.2
list:插入较多情况;
vector:动态数组;
deque:需要头部和尾部增删的情况;
map:字典;
set:添加忽略关键字;
11.3
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main() {
map<string, size_t> word_count;
string words;
while (cin>>words)
{
++word_count[words];
}
for (const auto &s : word_count)
cout << s.first << " occurs " << s.second << ((s.second > 1) ? " times " : " time ") << endl;
return 0;
}
11.4
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<set>
using namespace std;
int main() {
map<string, size_t> word_count;
set<string>exclude{ "you","i" };
string words;
while (cin>>words)
{
words.erase(find_if(words.begin(), words.end(), ::ispunct), words.end()); //删除单词后面的标点
for_each(words.begin(), words.end(), [](char& c) {c = tolower(c); }); //单词转换为小写
if(exclude.find(words)==exclude.end()) //忽略部分单词
++word_count[words];
}
for (const auto &s : word_count)
cout << s.first << " occurs " << s.second << ((s.second > 1) ? " times " : " time ") << endl;
return 0;
}
11.5
set中只有关键字;
map包括关键字-值对;
11.6
set关联式容器,查找较快;
list顺序容器,查找关键字与容器的大小有关;
11.7
#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;
int main() {
map<string, vector<string>> family;
string first_name, last_name;
cin >> last_name;
while (cin >> first_name)
{
family[last_name].push_back(first_name);
}
for (const auto f : family) {
cout << f.first << endl;
for (const auto s : f.second)
cout << s << " ";
cout << endl;
}
return 0;
}
11.8
效率更高,不用遍历判断重复;
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
vector<string>vs;
string s;
while (cin >>s)
{
if (find(vs.begin(), vs.end(), s) == vs.end())
vs.push_back(s);
}
for (const auto s : vs)
cout << s << " ";
cout << endl;
return 0;
}
11.9
map<string,list<size_t>> words_line;
11.10
对于有序容器必须定义元素的比较方法,默认<;
vector<int>::iterator 可以,因为定义了<;
list<int>::iterator不可以,未定义<;
11.11
#include <set>
#include <iostream>
#include <string>
#include "../ch07_Classes/Sales_data_ex26.h"
bool compareIsbn(const Sales_data &sales_data1, const Sales_data &sales_data2)
{
return sales_data1.isbn() < sales_data2.isbn();
}
int main()
{
using COMPAREISBN = bool (*)(const Sales_data &sales_data1, const Sales_data &sales_data2);
// std::multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
std::multiset<Sales_data, COMPAREISBN> bookstore(compareIsbn);
return 0;
}
11.12
#include<iostream>
#include<string>
#include<vector>
#include<utility>
using namespace std;
int main() {
vector<pair<string, int>>vp;
int i;
string s;
while (cin>>s>>i)
{
//vp.push_back(pair<string, int>(s, i));
//vp.push_back({ s,i });
vp.push_back(make_pair(s, i));
//vp.emplace_back(s, i);
}
for (const auto p : vp)
cout << p.first << " " << p.second << endl;
return 0;
}
11.13
#include<iostream>
#include<string>
#include<vector>
#include<utility>
using namespace std;
int main() {
vector<pair<string, int>>vp;
int i;
string s;
while (cin>>s>>i)
{
//vp.push_back(pair<string, int>(s, i));
//vp.push_back({ s,i });
vp.push_back(make_pair(s, i));
//vp.emplace_back(s, i);
}
for (const auto p : vp)
cout << p.first << " " << p.second << endl;
return 0;
}
11.14
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<utility>
using namespace std;
int main() {
map<string, vector<pair<string, string>>> family;
string first_name, last_name, birthday;
cin >> last_name;
while (cin >> first_name >> birthday)
{
family[last_name].push_back(make_pair(first_name, birthday));
for (const auto f : family) {
cout << f.first << endl;
for (const auto s : f.second)
cout << s.first << " " << s.second << endl;
}
return 0;
}
}
11.15
mapped_type: vector<int>
key_type: int;
value_type: pair<const int,vector<int>>
11.16
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main() {
map<int, string> m = { {1,"aa" } };
auto m_iter = m.begin();
m_iter->second = "bb";
cout << m_iter->first << " " << m_iter->second << endl;
return 0;
}
11.17
copy(v.begin(), v.end(), inserter(c, c.end())); //合法
copy(v.begin(), v.end(), back_inserter(c)); //非法,set中没有push_back()
copy(c.begin(), c.end(), inserter(v, v.end())); //合法
copy(c.begin(), c.end(), back_inserter(v)); //合法
11.18
map<string,size_t>::const_iterator map_it =word_count.cbegin();
11.19
using COMPAREISBN = bool (*)(const Sales_data &sales_data1, const Sales_data &sales_data2);
// std::multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
std::multiset<Sales_data, COMPAREISBN> bookstore(compareIsbn);
std::multiset<Sales_data, COMPAREISBN>::iterator bookstore_iter = bookstore.begin();
11.20
使用下标更加简单;
#include<iostream>
#include<string>
#include<map>
#include<utility>
using namespace std;
int main() {
map<string, size_t>word_count;
string word;
while (cin>>word)
{
pair<map<string, size_t>::iterator, bool> ret = word_count.insert({ word,1 });
if (!ret.second)
++ret.first->second;
}
for (const auto s : word_count)
cout << s.first << " " << s.second << endl;
return 0;
}
11.21
word_count.insert({word, 0})//得到insert的返回值pair
word_count.insert({word, 0}).first//得到map的迭代器
word_count.insert({word, 0}).first->second//map中size_t的值
++word_count.insert({word, 0}).first->second//递增该值
11.22
#include<iostream>
#include<string>
#include<map>
#include<utility>
#include<vector>
using namespace std;
int main() {
map<string, vector<int>> m1;
pair<map<string, vector<int>>::iterator, bool> ret = m1.insert({ "aaaa",{1,2,3,4,5}});
return 0;
}
11.23
#include<iostream>
#include<string>
#include<vector>
#include<utility>
#include<map>
#include<algorithm>
using namespace std;
int main() {
multimap<string, vector<string>> family;
string first_name, last_name;
vector<string>vs;
cin >> last_name;
while (cin>>first_name)
{
vs.push_back(first_name);
}
family.insert({ last_name,vs });
for (const auto f : family) {
cout << f.first << endl;
for (const auto s : f.second)
cout << s << " ";
cout << endl;
}
return 0;
}
11.24
向m中添加一个关键字为0的元素,并将其值初始化为1;
11.25
将容器第一个元素赋值为1;
11.26
可以用key_type对一个map进行下标操作;
下标操作返回mapped_type;
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main() {
map<int, string>m1 { {1, "dasda"} };
map<int, string>::key_type i1 = 1;
map<int, string>::mapped_type s1;
s1 = m1[i1];
cout << i1 << " " << s1 << endl;
return 0;
}
11.27
统计该元素有多少关键字用count
查看特定元素是否在容器内用find;
11.28
#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;
int main() {
map<string, vector<int>>m1{ {"aa",{1,2,3}} };
map<string, vector<int>>::iterator i_iter = m1.find("aa");
return 0;
}
11.29
lower_bound和upper_bound会返回相等的迭代器——都指向给定关键字的插入点,能保持容器中元素顺序的插入位置;
equal_range返回一个pair,pair中两个迭代器都指向元素可以插入的位置;
11.30
第一个迭代器的解引用后得到的书名;
11.31
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main() {
multimap<string, string>m{ {"a","abc"},{"a","avb"} };
auto cnt = m.count("a");
cout << cnt << endl;
while (cnt)
{
m.erase(m.find("a"));
--cnt;
}
for (const auto & s : m)
cout << s.first << " " << s.second << endl;
return 0;
}
11.32
#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;
int main() {
multimap<string, string>m{ {"a","abc"},{"a","avb"},{"b","dasdsa"},{"b","sdad"},{"c","fdsdfds"}};
map<string, vector<string>> m_ordered;
for (const auto p : m)
m_ordered[p.first].push_back(p.second);
for (const auto& p : m_ordered)
{
cout << p.first << endl;
for (const auto s : p.second)
cout << s << " ";
cout << endl;
}
return 0;
}
11.33
#include <map>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
map<string, string> buildMap(ifstream &map_file)
{
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 map<string, string> &m)
{
auto map_it = m.find(s);
if(map_it != m.cend())
return map_it->second;
else
return s;
}
void word_tranform(ifstream &map_file, ifstream &input)
{
auto trans_map = buildMap(map_file);
// for(const auto p : trans_map)
// cout << p.first << "->" << p.second << endl;
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()
{
ifstream map_file("word_transformation.txt"), input("word_transformation_bad.txt");
word_tranform(map_file, input);
return 0;
}
11.34
当map中没有这个元素时会插入元素,与预期不符;
11.35
在这里没有影响,如果关键字出现多次,使用下标会重复赋值,最后保存的是最后一个值,使用insert只插入第一个;
11.36
value.size() > 1 为false,将会抛出异常“no rule for” + key;
11.37
无序容器会有更好地平均性能;
11.38
单词计数程序;
#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 (const auto& w : word_count)
cout << w.first << " occurs " <<w.second<< ((w.second > 1) ? " times" : " time") << endl;
return 0;
}
单词转换程序
#include <unordered_map>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
unordered_map<string, string> buildMap(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 map_it = m.find(s);
if(map_it != m.cend())
return map_it->second;
else
return s;
}
void word_tranform(ifstream &map_file, ifstream &input)
{
auto trans_map = buildMap(map_file);
// for(const auto p : trans_map)
// cout << p.first << "->" << p.second << endl;
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()
{
ifstream map_file("word_transformation.txt"), input("word_transformation_bad.txt");
word_tranform(map_file, input);
return 0;
}