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#