STL容器之map
map可以理解为之中关联数组,之所以称为关联是因为map是通过键值来访问,而不是通过元素在数组中的位置来访问。
map的键类型必须满足严格弱排序,解释一下:
1.当键值与自身比较时,一定产生false结果
2.两个键不能相互小于,而且如果 k1<k2, k2<k3 那么 k1<k3
3.如果两个键值相互不小于,则视为相等
map定义的类型:
map<k, v>::key_type;键的类型
map<k, v>::mapped_type;键所关联值的类型
map<k, v>::value_type;一个pair类型,pair类型就是包含两个类型的一种模板类型,这两种类型不要求相同,例如pair<string, string> a;它具有两个共有数据成员,first和second。说回value_type,它的first元素具有const map<k, v>::key_type类型,second元素具有const map<k, v>::mapped_type类型
map的构造函数有有如下三种:
map<k, v> m;//空的map,键和值类型分别为k和v
map<k, v> m(m2);//初始化m为m2的副本,m2与m必须有相同的k,v类型
map<k, v> m(b, e);//创建m,存储迭代器b和e标记范围内元素的副本,元素的类型必须能转换为pair<const k, v>类型
map提供了如下的函数,具体函数原型和用法请参阅相关技术文档,
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
earse函数有三种形式:
void erase( iterator pos );
void erase( iterator start, iterator end );
size_type erase( const KEY_TYPE &key );//返回删除元素的个数
insert函数比较特别,也比较麻烦,这里着重介绍一下。
insert函数有三种形式:
iterator insert( iterator pos, const pair<KEY_TYPE,VALUE_TYPE> &val );
插入val到pos的后面,然后返回一个指向这个元素的迭代器。
void insert( input_iterator start, input_iterator end );
插入start到end的元素到map中。
pair<iterator, bool> insert( const pair<KEY_TYPE,VALUE_TYPE> &val );
只有在val不存在时插入val。返回值是一个指向被插入元素的迭代器和一个描述是否插入的bool值。
第三种形式特别值得注意,返回值是一个pair类型,pair.first是map<k, v>::value_type类型的迭代器,pair.second是bool,表示是否插入了元素,该函数的用法将在下面程序中有详细使用和说明。
请看下面程序:
#include <iostream>
#include <map>
#include <utility>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string str = "Ronnie John Mark Mark Judd Ronnie Ronnie";
istringstream is(str);
map<string, int> word_count;
string name;
/*此段程序是一个简单的单词个数统计程序,统计在字符串str中各个单词出现的个数,用一个map对象存储,键表示单词,值表示出现次数
while(is >> name){
//用下表操作符访问map中的元素时,如果该对应的键值不存在,则建立一个新的键值对插入map中。
++word_count[name];
}
*/
//下面用insert重写一下上面的程序,实现同样的功能,insert的好处是不会像下表操作符产生不必要的初始化。
cout << "------------------------------------" << endl;
while(is >> name){
//ret的类型定义比较难理解,可以仔细看看
pair<map<string, int>::iterator, bool> ret = word_count.insert(make_pair(name, 1));
if(!ret.second)
++ret.first->second;
}
cout << "Ronnie:\t" << word_count["Ronnie"] << endl;
cout << "John:\t" << word_count["John"] << endl;
cout << "Mark:\t" << word_count["Mark"] << endl;
cout << "Judd:\t" << word_count["Judd"] << endl;
//下面是map中其他的一些操作
//count,返回元素出现的次数,在map中只能是0,1,主要用来判断元素是否存在
cout << "------------------------------------" << endl;
cout << "count():" << endl;
if(word_count.count("Ronnie"))
cout << "Ronnie exists"<< endl;
//find,查找具有指定键值的元素的迭代器,如不存在,返回end迭代器。
cout << "------------------------------------" << endl;
cout << "find():" << endl;
map<string, int>::iterator map_it = word_count.find("John");
if(map_it != word_count.end())
cout << "John occurs " << map_it->second << " times" << endl;
else
cout << "John doesn't exist" << endl;
//用迭代器遍历map对象
cout << "------------------------------------" << endl;
cout << "travel map:" << endl;
for(map<string, int>::iterator it = word_count.begin(); it != word_count.end(); ++it)
cout << it->first << " occurs " << it->second << " times" << endl;
cout << "------------------------------------" << endl;
return 0;
}