Bootstrap

C++ STL Map的创建、删除、插入、更新、遍历

C++map容器提供一个键值对容器,mapmultimap差别仅仅在于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排序的时候

 

mapSTL里面的一个模板类,来看下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>lessSTL里面的一个函数对象

 

 

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# 





;