《C++ Primer》笔记 第十一章 关联容器
关联容器支持高效的关键字查找和访问。
map:关键字-值
set:每个元素只包含一个关键字(常用于判断一个值是否存在)
11.1
关联容器的元素是按关键词来保存和访问的,顺序容器是按他们在容器中的位置来顺序访问
11.2
list:任意位置插入添加
vector:相关联数据,顺序处理
deque:信息处理,只在头部
map:存储字典型数据
set:检测一个值是否存在
11.3
#include <iostream>
#include <map>
#include <string>
#include <set>
using namespace std;
int main()
{
map<string, size_t> word_count;
set<string> exclude = { "The","But" };
string word;
while (cin >> word)
if(exclude.find(word)==exclude.end())
++word_count[word];
for (const auto &w : word_count)
cout << w.first << " " << w.second
<< ((w.second > 1) ? " times" : " time") << endl;
system("pause");
}
11.4
将每个单词转换为小写,并消除标点
#include<cctype> //ispunct()
#include<algorithm>//remove_if
string::iterator it1;
for (it1 = word.begin(); it1 != word.end(); ++it1)
{
*it1 = tolower(*it1);
}
word.erase(remove_if(word.begin(), word.end(), ispunct),word.end());
++word_count[word];
关联容器的迭代器都是双向的。
11.5
单独关键字:set
键值对:map
11.6
set中的元素不可以重复、且有序
11.7
#include <iostream>
#include <map>
#include <string>
#include <set>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
map<string, vector<string>> family;
string firstName, childName;
while ([&]()->bool {cout << "请输入家庭的姓:";
return cin >> firstName && (firstName != "end"); }())
{
cout << "请输入孩子们的名字:";
while (cin >> childName && (childName != "end"))
{
family[firstName].push_back(childName);
}
}
for (const auto &f : family)
{
cout << f.first << "氏家族的孩子名字有";
for (auto it = f.second.begin(); it != f.second.end();++it)
cout << *it << " ";
cout << endl;
}
system("pause");
}
11.8
while(cin>>new_word)
{
if (find(word.begin(),word.end(),new_word) != word.end())
{
cout<<"不可输入重复元素";
}
else
{
word.push_back(new_word);
}
}
11.9
map<string,list
11.10
vector可以,因为其迭代器定义了大小比较的操作,而list的迭代器则没有,所以不可以
11.11
multiset<Sales_data, bool(*)(const Sales_data&, const Sales_data&)>
bookStore(compareIsbn);
11.12
#include <iostream>
#include <map>
#include <string>
#include <set>
#include<cctype>
#include<vector>
#include<algorithm>
#include<utility>
using namespace std;
int main()
{
vector<pair<string, int>> vec;
string tempFst;
int tempSec;
while ([&]()->bool {cout << "输入string:";
return cin >> tempFst &&(tempFst!=""); }())
{
cout << "输入int:";
cin >> tempSec;
vec.push_back({ tempFst,tempSec });
}
for (auto x : vec)
{
cout << x.first << " " << x.second << endl;
}
system("pause");
}
11.13
vec.push_back(std::make_pair(str, i));
vec.push_back({str, i});
vec.emplace_back(str, i);
vec.push_back(pair<string,int>(str,i));
11.14
map<string,vector<pair<string,string>>> family;
类比11.14和11.7,也是while中利用lambda表达式。
11.15
mapped_type:vector<int>
key_type:int
value_type:pair<int,vector<int>>
11.16
只能改value的值,不能改关键字的值。注意此即可
11.17
第二个不对。multiset不支持push_back。
11.18
map<string,size_t>::iterator
11.19
multiset<Sales_data,
bool(*) (const Sales_data&, const Sales_data&)>::iterator;
11.20
auto ret = word_count.insert({word, 1});
if (!ret.second) ++ret.first->second;
11.21
将word对应的value加一(0->1)
11.22
参数类型:pair(string,vector<int>)
返回类型:pair<map<sring,vector<int>>::iterator,bool>
11.23
直接改成multimap即可,注意重复元素。
11.24
insert({0,1});
11.25
报错
11.26
key_type
mapped_type
11.27
计数:count
存在:find
11.28
map<string, vector<int>>::iterator it = mp.find(s);
11.29
尾后迭代器
尾后迭代器
pair(ite.end(),ite.end())
11.30
对返回的pair中第一个迭代器进行解引用,输出它的second值(value)
11.31
auto iter = authors.find("xxx");
auto n = authors.count("xxx");
while(n--) {
authors.erase(iter++);
}
11.32
auto iter = authors.begin();
while(iter != authors.end())
{
cout <<iter->first << " "<< iter->second<<endl;
iter++;
}
11.33 书上的就挺好
#include <iostream>
#include <map>
#include <string>
#include <set>
#include<cctype>
#include<vector>
#include<algorithm>
#include<utility>
#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 && 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.end())
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 first_word = true;
while (stream >> word)
{
if (first_word)
first_word = false;
else
cout << " ";
cout << transform(word, trans_map);
}
cout << endl;
}
}
11.34
函数为const,无法修改map
11.35
当重复出现相同key时,下标操作后value会被替换,而insert不会。
11.36
不会受到影响,因为仅包含一个key和一个空格,buildmap函数中判断value.size()<=1, 即后面没有value则抛出异常
11.37
无序版本优势:当容器中key没有明显的顺序关系时更有用,且不需要耗费多余的时间来维护容器中的key序列
有序版本优势:当容器中key有明显的顺序关系时更有用,且我们不需要考虑排序问题,容器自动维护序列(字典序)
11.38
直接改类型即可。
7/4/2019 7:00:59 PM