11、C++ Primer 4th 笔记,关联容器(1)

1、关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素。

2map 的元素以键-值(key-value)对的形式组织:键用作元素在 map 中的索引,而值则表示所存储和读取的数据。

3、关联容器类型

map

关联数组:元素通过键来存储和读取

set

大小可变的集合,支持通过键实现的快速读取

multimap

支持同一个键多次出现的 map 类型

multiset

支持同一个键多次出现的 set 类型

4pair类型

pairs 类型提供的操作

pair<T1, T2> p1;

创建一个空的 pair 对象,它的两个元素分别是 T1 T2类型,采用值初始化

pair<T1, T2> p1(v1, v2);

创建一个 pair 对象,它的两个元素分别是 T1 T2 ,其中 first 成员初始化为 v1,而 second 成员初始化为 v2

make_pair(v1, v2)

v1v2值创建一个新pair对象,其元素类型分别是v1v2的类型

p1 < p2

两个 pair 对象之间的小于运算,其定义遵循字典次序:如果 p1.first < p2.first 或者!(p2.first < p1.first) && p1.second < p2.second,则返回 true

p1 == p2

如果两个 pair 对象的 first second 成员依次相等,则这两个对象相等。该运算使用其元素的 == 操作符

p.first

返回 p 中名为 first 的(公有)数据成员

p.second

返回 p 的名为 second 的(公有)数据成员

5map构造函数

map<k, v> m;

创建一个名为 m 的空 map 对象,其键和值的类型分别为 k v

map<k, v> m(m2);

创建 m2 的副本 mm m2 必须有相同的键类型和值类型

map<k, v> m(b,e);

创建 map 类型的对象 m,存储迭代器 b e 标记的范围内所有元素的副本。元素的类型必须能转换为 pair<const k, v>

6、所有比较函数必须在键类型上定义严格弱排序,即键类型必须定义 < 操作符。

7map定义的类型

map<K, V>::key_type

map 容器中,用做索引的键的类型

map<K, V>::mapped_type

map 容器中,键所关联的值的类型

map<K, V>::value_type

一个pair类型,它的 first 元素具有 const map<K, V>::key_type类型,而 second 元素则为 map<K,V>::mapped_type 类型;它的值成员可以修改,但键成员不能修改。

    map迭代器进行解引用将产生pair类型的对象。用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值;类类型的元素用默认构造函数初始化,而内置类型的元素则初始化为0

8map 迭代器返回 value_type 类型的值——包含 const key_type mapped_type 类型成员的 pair 对象;下标操作符则返回一个 mapped_type 类型的值。

9map插入数据

m.insert(e) 

e 是一个用在 m 上的 value_type 类型的值。如果键(e.first)不在 m 中,则插入一个值为 e.second 的新元素;如果该键在 m 中已存在,则保持 m 不变。该函数返回一个pair 类型对象,包含指向键为 e.first 的元素的map迭代器,以及一个bool类型的对象,表示是否插入了该元素

m.insert(beg,end)

beg end 是标记元素范围的迭代器,其中的元素必须为m.value_type

类型的键-值对。对于该范围内的所有元素,如果它的键在 m 中不存在,则将该键及其关联的值插入到 m。返回 void 类型

m.insert(iter,e)

e 是一个用在 m 上的 value_type 类型的值。如果键(e.first)不在 m 中,则创建新元素,并以迭代器 iter 为起点搜索新元素存储的位置。返回一个迭代器,指向 m 中具有给定键的元素

示例

word_count.insert(map<string, int>::value_type("Annna", 1));
//the following is equivalent to the above
word_count.insert(make_pair("Anna", 1));
pair<map<string, int>::iterator, bool> ret =  word_count.insert(make_pair(word, 1));

10map查找

m.count(k)

返回 m k 的出现次数

m.find(k)

如果 m 容器中存在按 k 索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器

11map删除

m.erase(k)

删除 m 中键为 k 的元素。返回 size_type 类型的值,表示删除的元素个数

m.erase(p)

m 中删除迭代器 p 所指向的元素。p 必须指向 m 中确实存在的元素,而且不能等于 m.end()。返回 void

m.erase(b, e)

m 中删除一段范围内的元素,该范围由迭代器对 b e 标记。b e 必须标记 m 中的一段有效范围:即 b e 都必须指向m中的元素或最后一个元素的下一个位置。而且,b e 要么相等(此时删除的范围为空),要么 b 所指向的元素必须出现在 e 所指向的元素之前。返回 void 类型

12set

    set容器只是单纯的键的集合,当只想知道一个值是否存在时,使用set很适合。set支持大部分的map操作,如insert,count,find,erase操作等。两种例外:set不支持下标操作符,而且没有定义 mapped_type 类型。在 set 容器中,value_type 不是 pair 类型,而是与 key_type 相同的类型。它们指的都是 set 中存储的元素类型。这一差别也体现了 set 存储的元素仅仅是键,而没有所关联的值。与 map 一样,set 容器存储的键也必须唯一,而且不能修改。

一个例子程序

#include "map"
#include "string"
#include "fstream"
#include "iostream"
#include "sstream"
using namespace std;

// opens in binding it to the given file
ifstream& open_file(ifstream &in, const string &file)
{
	in.close(); // close in case it was already open
	in.clear(); // clear any existing errors
	// if the open fails, the stream will be in an invalid state
	in.open(file.c_str()); // open the file we were given
	return in; // condition state is good if open succeeded
}

int main(int argc, char **argv)
{
	map<string, string> trans_map;
    string key, value;
	if (argc != 3)
		throw runtime_error("Wrong number of arguments");
	ifstream map_file;
	if (!open_file(map_file, argv[1]))
		throw runtime_error("No transformation file");
	while (map_file >> key >>value)
	{
		trans_map.insert(make_pair(key, value));
	}

	ifstream input;
	if (!open_file(input, argv[2]))
	{
		throw runtime_error("No input file");
	}
	string line;
	while (getline(input, line))
	{
		istringstream mystream(line);
		string word;
		bool firstword = true;
		while (mystream >> word)
		{
			map<string, string>::iterator map_it = trans_map.find(word);
			if (trans_map.end() != map_it)
				word = map_it->second;
			if (firstword)
				firstword = false;
			else
				cout << " ";
			cout << word;
		}
		cout << endl;
	}
	return 0;
}

参考:

[1] http://blog.163.com/zhoumhan_0351/blog/static/399542272010227112325224/

http://blog.163.com/zhoumhan_0351/blog/static/39954227201032392545410/

原文地址:https://www.cnblogs.com/mydomain/p/1989392.html