C++ Primer学习笔记2--c++ 关联容器

来源:互联网 发布:淘宝开店手机充值 编辑:程序博客网 时间:2024/04/28 00:46


 1.两个基本的关联容器类型是 map set

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

                                

 set   仅包含一个键,并有效地支持关于某个键是否存在的查询。

 

 如果希望有效地存储不同值的集合,那么使用 set容器比较合 ,

  map 容器则更适用于需要存储(乃至修改)每个键所关联的值的情况。 

 

 在做某种文本处理时,可使用 set保存要忽略的单词。

 而字典则是 map的一种 很好的应用:单词本身是键,而它的解释说明则是值。

 

 不允许为同一个键 添加第二个元素。如果一个键必须对应多个实例,则需使用 multimap multi set,这两种类型允许多个元素拥有相同的键。

 

 2.<utility>   pair

 

 (1) pair<T1, T2>  p1;

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

 eg:

 pair<string, string> anon;       // holds two strings

 pair<string, int> word_count;    // holds a string and an int

 pair<string, vector<int> > line; // holds string and vector<int>

 如果在创建 pair对象时不提供初始化式,则调用默认构造函数对其成员采用值初始化。

 

 

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

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

 

 pair<string, string> author("James", "Joyce");

 

 利用 typedef 简化其声明:

 typedef pair<string, string> Author;

 Author proust("Marcel", "Proust");

 Author joyce("James", "Joyce");

 

(3) make_pair(v1,v2)

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

 pair<int, int> p1(1,2);

 pair<int, int> p2;

 p2 = make_pair(1, 2);

 

 (4)简单操作

 p1 < p2

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

 

 

 p1 == p2

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

 

 

 

 与其他标准库类型不同,对于 pair,可以直接访问其数据成员:其成员都是仅有的,分别命名为 first second

 p.first

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

 

 

 p.second

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

 

 3.关联容器

 关联容器不提供 front push_front pop_frontbackpush_back以及 pop_back 操作。

 在迭代遍历关联容器时,我们可确保按键的顺序的访问元素,而与元素在容器中的存放位置完全无关。

 

(1)map

 #include <map>

 在定义 map 对象时,必须分 别指明键和值的类型(value type)

 map<string, int>word_count;

 

 构造函数

 map<k, v> m;

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

 

 map<k, v> m(m2);

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

 

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

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

 

 map 对象的元素是键-值对,也即每个元素包含两个部分:键以及由键关联的值。

 value_type 是存储元素的键以及值的 pair 类型, 且键为 const

 例如,word_count 数组的 value_type pair<const string, int>类型。

 

 

 3种类型

 (1) map<K,V>::key_type map 容器中,用做索引的键的类型

 (2)map<K, V>::mapped_type map容器中,键所关联的值的类型

 (3)map<K,V>::value_type

 一个 pair 类型,它的 first 元素具有 const map<K, V>::key_type 类型, second 元素则为 map<K, V>::mapped_type 类型

 对迭代器进行解引用将获得一个 pair对象,它的 first成员存放键, const, second成员则存放值。


 2)给map添加元素

 a.使用下标

 map <string, int> word_count; // empty map

 // insert default initialzed element with key Anna; then assign 1 to its value

 word_count["Anna"] = 1;

 

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

 ---------------------

 *map下标编程的意思*


 对于 map 容器,如果下标所表示的键在容器中不存在,则添加新元素

 map<string, int> word_count; 

 string word;

 while (cin >> word)

 ++word_count[word];

 这段程序创建一个 map对象,用来记录每个单词出现的次数。

 while 循环 每次从标准输入读取一个单词。

 如果这是一个新的单词,则在 word_count中添 加以该单词为索引的新元素。

 如果读入的单词已在 map对象中,则将它所对应的值加 1

 其中最有趣的是,在单词第一次出现时,会在 word_count中创建并插入一 个以该单词为索引的新元素,

 同时将它的值初始化为 0。然后其值立即加 1,以每次在 map 中添加新元素时,

 所统计的出现次数正好从 1开始。

 -----------------------

 b. 使用insert

 

 m.insert(e)

 

 

 m.insert(beg,end)

 

 

 m.insert(iter,e)

 

 word_count.insert(map<string, int>::value_type("Anna", 1));

 

 map<string, int>::value_type(”anna“, 1)

 是一个新创建的 pair对象,将直接插入到 map容器中。谨记 value_type pair<const K, V>类型的同义词,K 为键类型, V是键所关联的值的类 型。insert的实参创建了一个适当的 pair 类型新对象,该对象将插入到 map容器。在添加新 map 元素时,使用 insert成员可避免使用下标操作符所带来 的副作用:不必要的初始化。

 传递给 insert 的实参相当笨拙。可用两种方法简化:使用 make_pair: 

    word_count.insert(make_pair("Anna", 1));

 

 或使用 typedef

 

 typedef map<string,int>::value_type valType;

 word_count.insert(valType("Anna", 1));

 

 带有一个键- pair形参的 insert 版本将返回一个值:包含一个迭代器和一个 bool 值的 pair对象,其中迭代器指向 map中具有相应键的元 , bool值则表示是否插入了该元素。如果该键已在容器中,则其关联的值保持不变,返回的 bool值为 true。在这两种情况下,迭代器都将指向具有给定键的元素。下面是使用 insert 重写的单词统计程序:

 map<string, int> word_count; // empty map from string to int

 string word;

 while (cin >> word) {

 // inserts element with key equal to word and value 1;

 // if word already in word_count, insert does nothing

 

 pair<map<string, int>::iterator, bool> ret =

 word_count.insert(make_pair(word, 1));

 if (!ret.second)          // word already in word_count

 ++ret.first->second;  // increment counter

 }

 

 3)查找并读取map中的元素

 a.使用下标

 map<string, int> word_count;

 int occurs = word_count["foot"];

 使用下标存在一个很危险的副作用:如果该键不在 map容器中,么下标操作会插入一个具有该键的新元素。

 此时occurs = 0;

 

 b.使用count

 

 word_count.count("foot");//返回foot的次数

 

 

 c.使用find//返回指向该元素的迭代器,不存在返回超出末端的迭代器

 int occurs = 0;

 map<string,int>::iterator it = word_count.find("foobar");

 if (it != word_count.end())

 occurs = it->second;

 

 

 3)从map中的删除元素

 

 

 m.erase(k)

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

 

 

 

 

 m.erase(p)

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

 

 

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

 

 4)遍历

 map 同样提供 begin end 运算,以生成用于遍历整个容器的迭代器。

 例如,可如下将 map容器 word_count 的内容输出:

 

 map<string, int>::const_iterator  map_it = word_count.begin();


 while (map_it != word_count.end()) {

 

 cout << map_it->first << " occurs "

 << map_it->second << " times" << endl;

 ++map_it; 

 

 

 }

 

 

 (2)set

  

  #include<set>

  

  

原创粉丝点击