您的位置:首页 > 编程语言 > C语言/C++

【语法回顾】C++STL:关联容器

2012-07-19 11:10 531 查看

一.关联容器的定义

  关联容器支持通过键来搞笑的查找和读取元素。两个基本的关联容器类型是map和set:map的元素以key-value对的形式组织:键用做元素在map中的索引,而值则表示所存储和读取的元素。set仅包含一个键,并有效的支持关于某个键是否存在的查询。关联容器还包括multimap,multiset,这2个关联容器中键的值不唯一。

二.pair类型

  之所以先介绍pair类型,是因为map就相当于是pair的集合,pair为一个基本单位,当然它也属于模板类,定义在头文件<utility>中。

  pair类的操作:

  pair<T1,T2> p1 // 创建一个空的pair对象,2种元素类型分别为T1,T2

  pair<T1,T2> p1(v1,v2); //创建一个pair对象,以v1,v2初始化2种元素

  p1.first p2.second // 在pair对象的实例种,第一个元素由first调用,第二个元素由second调用

  p1 < p2 p1 == p2 //遵循字典序对p1,p2的2个元素分别进行比较

if(p1.first == p2.first)
return p1.second<p2.second
else
return p1.first < p2.first


  注:p.first p.second都是p种的公有数据成员

三.map类型

1.map的定义

  map是键-值对的集合。map类型通常可理解为关联数组,而关联的本质在于元素的值与某个特定的键相关联,并非通过元素在数组种的位置来获取

map<k,v> m; //创建一个空的map对象

map<k,v> m1(m); //用另外一个map实例来初始化新的map,创建了m的副本

map<k,v> m2(b, e); //存储迭代器b,e之间的所有元素的副本。元素类型必须能转换为pair<const k, v>


   注:map对象种的键类型必须定义了<操作符,因为map元素序列在键类型上是严格若排序的,也就是说从小到大排列的。

map类定义的类型:

  map<k,v>::key_type //返回的是用作索引的键的类型

  map<k,v>::mapped_type //返回的是键所关联值的类型

  map<k,v>::value_type //返回的是一个pair类型

  注:map的迭代器解引用所产生的是一个pair类型的对象

map<int, string>::iterator  map_it = m.begin();
pair<int, string> p;
for(; map_it != m.end(); map_it++)
{
p = *map_it;
cout << p.first;
cout << p.second << endl;
*map_it->first = 0;
}


2.添加元素

A.下标访问map对象

map<string,int> m;
m["Anna"] = 1;  //键-值的赋值形式
map<string,int>::iterator map_it = m.find("Anna"); //获得指向Anna的指针
cout << m["Anna"] << endl;   // 2种输出方式
cout << map_it->second << endl;


  如果下标所标示的键不存在,程序会自动新建该键,创建该pair对象。

B.使用map::insert

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

  word_count.insert(iter1, iter2); //iter1,iter2分别为标志元素范围的迭代器,对于该范围内的所有元素,如果它的键不存在,则将该键及其关联的值插入到m种。返回void

insert的返回值: 包含一个迭代器和一个bool类型

该实例通过判断插入是否成功,判断要插入的键是否存在,已存在那就对计数器加1

map<string, int> word_count;
string word;
while(cin >> word)
{
pair<map<string,int>::iterator, bool> ret = word_count.insert(make_pair(word,1));
if(!ret.second)
++ret.first->second;
}


3.查找元素

map<string,int> word_count;
int occurs = word_count["Anna"];  // 获取相应键的值
int count = word_count.count["the"]; // 获得word_count种the出现的次数,多用在multimap,multiset
map<string,int>::iterator  map_it = word_count.find["the"];
occurs = map_it->second; 


4.删除元素

  map容器中删除元素使用erase,跟顺序容器不同,map种erase返回void,而顺序容器返回一个迭代器,指向呗删除元素后面的元素。

m.erase(k) //删除m种键为k的元素,返回size_type类型的值,表示删除的元素个数

m.erase(p) // p为迭代器,删除p迭代器所指向的确切元素

m.erase(b, e) //删除一段元素,b,e均为迭代器

5.迭代遍历

map<string, int>::const_iterator  map_it = word_count.begin();
for(; map_it != word_count.end(); map_it++)
{
cout << map_it->first << map_it->second << endl;
}


四.set类型

转自:http://www.cnblogs.com/dongzhiquan/archive/2011/01/06/1994521.html

  一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。
  在所有构造方法以及 add、equals 和 hashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从 Collection 接口所继承的内容。出于方便考虑,它还包括了其他继承方法的声明(这些声明的规范已经专门针对 Set 接口进行了修改,但是没有包含任何其他的规定)。对这些构造方法的其他规定是(不要奇怪),所有构造方法必须创建一个不包含重复元素的 set(正如上面所定义的)。注:如果将可变对象用作 set 元素,那么必须极其小心。如果对象是 set 中某个元素,以一种影响 equals 比较的方式改变对象的值,那么 set 的行为就是不确定的。此项禁止的一个特殊情况是不允许某个 set 包含其自身作为元素。
常用的几个方法
  boolean add(E e)
  如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。
  boolean addAll(Collectionc)
  如果 set 中没有指定 collection 中的所有元素,则将其添加到此 set 中(可选操作)。
  void clear()
  移除此 set 中的所有元素(可选操作)。
  boolean contains(Object o)
  如果 set 包含指定的元素,则返回 true。
  boolean containsAll(Collectionc)
  如果此 set 包含指定 collection 的所有元素,则返回 true。
  boolean equals(Object o)
  比较指定对象与此 set 的相等性。
  int hashCode()
  返回 set 的哈希码值。
  boolean isEmpty()
  如果 set 不包含元素,则返回 true。
  Iterator iterator()
  返回在此 set 中的元素上进行迭代的迭代器。
  boolean remove(Object o)
  如果 set 中存在指定的元素,则将其移除(可选操作)。
  boolean removeAll(Collectionc)
  移除 set 中那些包含在指定 collection 中的元素(可选操作)。
  boolean retainAll(Collectionc)
  仅保留 set 中那些包含在指定 collection 中的元素(可选操作)。
  int size()
  返回 set 中的元素数(其容量)。
  Object[] toArray()
  返回一个包含 set 中所有元素的数组。
  T[]
  toArray(T[] a)

  返回一个包含此 set 中所有元素的数组;返回数组的运行时类型是指定数组的类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: