#include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
#include<string>
#include<map>
#include<set>
using namespace std;
//两个主要的关联容器:map和set
//使用关联容器
//map
void test01() {
//单词计数程序
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;
//使用set
//可以使用set保存想要忽略的单词
set<string>exclude = { "the", "but", "and", "or", "an", "a" };
while (cin >> word)
if (exclude.find(word) == exclude.end())
++word_count[word];
}
//关联容器
/*
关联容器不支持顺序容器的位置相关的操作,关联容器的迭代器都是双向的,当定义一个
map时,必须既要指定关键字类型也要指明值得类型,而定义一个set时,只需要指明关键字的类型
*/
//初始化multimap和multiset
void test02() {
vector<int>ivec;
for (vector<int>::size_type i = 0; i != 10; i++) {
ivec.push_back(i);
ivec.push_back(i);
}
set<int>iset(ivec.cbegin(), ivec.cend());
multiset<int>miset(ivec.cbegin(), ivec.cend());
cout << ivec.size() << endl;
cout << iset.size() << endl;
cout << miset.size() << endl;
}
//书上的378,379关键字类型的要求和使用关键词类型的比较函数
//pair类型(声明在头文件中的utility中)
void test03() {
pair<string, string>anon;
pair<string, size_t>word_count;
pair<string, vector<int>>line;
pair<string, string>author{ "james", "joyce" };
cout << author.first << author.second << endl;
}
//创建pair对象的函数
pair<string, int> process(vector<string>& v) {
if (!v.empty())
return { v.back(), v.back().size() };
else
return pair<string, int>(); //隐式构造返回值
}
//set的迭代器是const的
/*
虽然set类型同时定义了iterator和const_iterator类型,但是两种类型都只允许只读set中的元素,与不能改变一个
map元素的关键字一样,一个set中的关键字也是const的
*/
void test04() {
set<int>iset = { 0, 1, 2, 3, 4 };
set<int>::iterator set_it = iset.begin();
if (set_it != iset.end()) {
//*set_it = 42; 错误,set中的关键字只是可读的
cout << *set_it << endl;
}
}
//当使用一个迭代器遍历一个map,multimap,set和multiset时,迭代器按关键字升序遍历元素
//添加元素
void test05() {
vector<int>ivec = { 2, 4, 5, 8, 9 };
set<int>set2;
set2.insert(ivec.cbegin(), ivec.cend());
set2.insert({ 1, 2, 4, 5 });
//向一个map中添加元素
/*
对一个map进行insert操作时,必须记住元素的类型为pair
*/
string word;
map<string, int>word_count;
word_count.insert(make_pair(word, 1));
word_count.insert(pair<string, size_t>(word, 1));
word_count.insert(map<string, size_t>::value_type(word, 1));
//检测insert的返回值
/*
insert,emplace的返回值依赖于容器的类型和参数,对于不包含重复关键字的容器,添加单一元素的insert和emplace版本返回一个pair
告诉我们插入操作是否成功,pair的first成员是一个迭代器,指向具有给定关键字的元素,second成员是一个bool值,指出元素是 插入
成功还是插入失败
*/
//向multiset和multimap添加元素
multimap<string, string>authors;
authors.insert({ "jjj", "llll" });
authors.insert({ "jjj", "1111" });
//对于允许重复关键字的容器,接受单个元素的insert操作返回一个指向新元素的迭代器,这里无需返回一个bool值
}
//删除元素
void test06() {
map<string, int>word_count;
string removal_word;
if (word_count.erase(removal_word))
cout << removal_word << endl;
else
cout << "not found" << endl;
//erase返回实际删除元素的数量,对于允许重复关键字的容器,删除元素的数量可能大于1
}
//map的下标操作
void test07() {
map<string, size_t>word_count;
word_count["Anna"] = 1;
word_count.at("Anna");
//访问元素
set<int> iset = { 0, 1, 2, 3, 4 };
iset.find(1);
iset.find(11);
iset.count(1);
iset.count(11);
//对map使用find代替下标操作
if (word_count.find("foobar") == word_count.end())
cout << "foobar is not in the map" << endl;
//在multimap和multiset中查找元素
//如果一个multimap和multiset中有多个元素具有给定关键字,则这些元素在容器中会相邻存储
string search_item("Alain de botton");
multiset<string>authors;
auto entries = authors.count(search_item);
auto iter = authors.find(search_item); //获得一个迭代器,指向第一个关键字为此作者的元素
while (entries) {
cout << iter->second << endl;
++iter;
--entries;
}
//我们还可以使用lower_bound 和upper_bound
for (auto beg = authors.lower_bound(search_item), end = authors.upper_bound(search_item);beg != end;++beg)
cout << beg->second << endl;
//equal_range 函数
/*
此函数接受一个关键字,返回一个迭代器pair,如果关键字存在,则第一个迭代器指向第一个与关键字匹配的元素
第二个迭代器指向最后一个匹配元素之后的位置,如果没有找到元素,则两个迭代器都指向关键字可以插入得位置
*/
for (auto pos = authors.equal_range(search_item); pos.first != pos.second; ++pos.first) {
cout << pos.first->second << endl;
}
}
//无序容器
void test07() {
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 << endl;
}
int main() {
system("pause");
return 0;
}