关联容器

#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;
}
posted @ 2022-03-17 17:38  W-forever  阅读(34)  评论(0)    收藏  举报