C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值。
map的实现是一颗红黑树,因此,map的内部键的数据都是排好序的,查找和删除、插入的效率都是lgN。
map的本质其实就是映射,键值(key-value)一一对应。比如身份证号(key)和姓名(value)一一对应,map的定义格式:
std::map <key_type, value_type> 变量;
比如人的身份证号和姓名,可以这样定义映射 std::map<int , string> mapPeople。
键(key)和值(value)可以是任意类型,对key的类型要求是必须支持<操作符。
1 头文件
#include <map>
不能加扩展名.h
2 定义
std::map <key_type, value_type> 变量;
即
std::map<int , string> PeopleMap;
或者是typedef std::map<int , string> mapPeopleType;
mapPeopleType PeopleMap;
3 插入数据
(1) map的变量名[key] = value;
PeopleMap[111] = string(“zhang san”); //常用的
(2) PeopleMap.insert(map<int, string>::value_type(111, “zhang wu” ));
可以根据insert的返回值判断释放插入成功
The single element versions (1) return a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element with an equivalent key in the map. The pair::second element in the pair is set to true if a new element was inserted or false if an equivalent key already existed.
也就是说insert返回的是一个pair,这个pair的成员first等于key,而second成员,成功将被设置为true,失败设置为false。
(3) PeopleMap.insert(pair<int , string>(222 ,"zhang liu")); //常用的
(4) PeopleMap.insert(make_pair<int , string>(222 ,"zhang liu")); //常用的
insert方法和数组方法的区别
Insert方法不能覆盖,如果键已经存在,则插入失败
数组方法,就算键已经存在,使用数组方法,将会直接更新键对应的值。
4 查找数据和修改数据
(1) string value = PeopleMap[333];
PeopleMap[333] = string(“lilei”);
(2) mapPeopleType ::iterator Itr;
Itr = PeopleMap.find("b"); //find(key)
value = my_Itr->second;
Itr->second = new value;
不过注意,键本身是不能被修改的,除非删除。
5 删除数据
(1) PeopleMap.erase(my_Itr);
(2) PeopleMap.erase(key);
还是注意,第一种情况在迭代期间是不能被删除的
6 迭代数据 、遍历
for (Itr=PeopleMap.begin(); Itr!=PeopleMap.end(); ++Itr) {}
7.排序
map的排序默认是根据key从小到大排序,需要注意的是:
(1)按照key从大到小排序
(2)当key是一个结构体的时候
(3)想按value排序的时候
map是STL里面的一个模板类,来看下map的定义
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> > // map::allocator_type
> class map;
他的四个参数,第一个是key,第二个是value,这个大家都知道。
第三个是跟排序有关,第四个设置存储分配模型的
现在我们来重点看第三个跟排序有关的:
class Compare = less<Key>
这是一个class类型,默认是less<Key>,less是STL里面的一个函数对象
8 反向迭代器
mapPeopleType ::reverse_iterator Itr;
Itr = PeopleMap.rbegin();
While(Itr != PeopleMap.rend())
{
Itr++;
}
9 其它方法
PeopleMap.size() 返回元素数目
PeopleMap.empty() 判断是否为空
PeopleMap.clear() 清空所有元素
可以直接进行赋值和比较:=, >, >=, <, <=, != 等等
#include <iostream>
#include <string>
#include <map>
typedef std::map<int , std::string> mapPeopleType;
void for_each(mapPeopleType &PeopleMap)
{
mapPeopleType::iterator itr = PeopleMap.begin();
std::cout<< "for_each "<<std::endl;
while(itr != PeopleMap.end())
{
std::cout<< " first "<< itr->first << " second "<<itr->second<<std::endl;
itr++;
}
}
void reverse_for_each(mapPeopleType &PeopleMap)
{
mapPeopleType::reverse_iterator itr = PeopleMap.rbegin();
std::cout<< "reverse_for_each "<<std::endl;
while(itr != PeopleMap.rend())
{
std::cout<< " first "<< itr->first << " second "<<itr->second<<std::endl;
itr++;
}
}
void add(mapPeopleType &PeopleMap)
{
std::cout<< " add "<<std::endl;
PeopleMap[333] = std::string("zhangsan_ver2");//覆盖更新
PeopleMap[444] = std::string("zhang444new"); //新增
std::pair< mapPeopleType::iterator, bool >insert_pair;
insert_pair = PeopleMap.insert(std::make_pair<int ,std::string>(222 ,"zhang liu"));//插入已存在的键值将会失败
//
if(insert_pair.second == false)
{
std::cout<< " first: "<< insert_pair.first->first << ", second: "<<"false"<<std::endl;
}
}
void my_find(mapPeopleType &PeopleMap)
{
std::cout<< " find :"<<std::endl;
mapPeopleType::iterator itr;
itr = PeopleMap.find(222);
if(itr != PeopleMap.end())
{
std::cout<< " first "<< itr->first << " second "<<itr->second<<std::endl;
}
else
{
std::cout<< "not found 222"<<std::endl;
}
itr = PeopleMap.find(22);
if(itr != PeopleMap.end())
{
std::cout<< " first "<< itr->first << " second "<<itr->second<<std::endl;
}
else
{
std::cout<< "not found 22"<<std::endl;
}
}
void del(mapPeopleType &PeopleMap)
{
std::cout<< " 444 :"<<std::endl;
mapPeopleType::iterator itr;
itr = PeopleMap.find(444);
if(itr != PeopleMap.end())
{
PeopleMap.erase(itr);
std::cout<< " 444 delete success"<<std::endl;
return ;
}
}
int main()
{
mapPeopleType PeopleMap;
PeopleMap[333] = std::string("zhangsan");
PeopleMap.insert(std::make_pair<int ,std::string>(222 ,"zhang liu"));
//遍历
for_each(PeopleMap);
//反向遍历
reverse_for_each(PeopleMap);
//添加数据
add(PeopleMap);
for_each(PeopleMap);
reverse_for_each(PeopleMap);
//查找
my_find(PeopleMap);
//删除
del(PeopleMap);
for_each(PeopleMap);
//其他
std::cout<< " size: "<< PeopleMap.size() << ", empty: "<<PeopleMap.empty()<<std::endl;
PeopleMap.clear();
std::cout<<"clear after"<< " size: "<< PeopleMap.size() << ", empty: "<<PeopleMap.empty()<<std::endl;
return 0;
}
root@ubuntu:/share# g++ map.cpp -g
root@ubuntu:/share# ./a.out
for_each
first 222 second zhang liu
first 333 second zhangsan
reverse_for_each
first 333 second zhangsan
first 222 second zhang liu
add
first: 222, second: false
for_each
first 222 second zhang liu
first 333 second zhangsan_ver2
first 444 second zhang444new
reverse_for_each
first 444 second zhang444new
first 333 second zhangsan_ver2
first 222 second zhang liu
find :
first 222 second zhang liu
not found 22
444 :
444 delete success
for_each
first 222 second zhang liu
first 333 second zhangsan_ver2
size: 2, empty: 0
clear after size: 0, empty: 1
root@ubuntu:/share#