一:map是关联式容器,它提供一对一的映射。存储的数据有两个部分,一个是关键字,一个是值,其中关键字只能出现一次,而不同的关键字,可以有相同的值。map中用pair来存储这两个值的。pair是stl定义的一种数据结构,后面会有简述。map内部自建一颗红黑树,所有map里面的数据都是有序的。
二:方法
1.构造函数,map有6个构造函数。但是我们通常用map<type1,type2> m;这种方法来构造一个map实例。
2.数据插入,map通常用下面的三种方式插入数据。
1),用insert方法插入pair数据。
1: void main( VOID )
2: {3: map<string,int> m;4: m.insert(pair<string,int>("sa",67));5: m.insert(make_pair<string,int>("sd",565));//用make_pair方法(函数)产生pair对象。6: map<string,int>::iterator it = m.begin();7: while(it!=m.end())
8: {9: cout<<it->first<<" "<<it->second<<endl;
10: it++;11: }12: }
2,)用insert函数插入value_type数据。
1: void main( VOID )
2: {3: map<string,int> m;4: m.insert(map<string,int>::value_type("sd",5));5: map<string,int>::iterator it = m.begin();6: while(it!=m.end())
7: {8: cout<<it->first<<" "<<it->second<<endl;
9: it++;10: }11: }
其实这个方法和上面的本质上是一样的。因为valud_type 就是pair类型的,只是换个方法而已,可以通过 cout<<typeid(map<string,int>::value_type).name()来获得 value_type的类型,得到类型为
struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>说明是个struct pair类型的。
3,)通过重载[]来插入数据。
1: void main( VOID )
2: {3: map<string,int> m;4: cout<<typeid(map<string,int>::value_type).name()<<endl;5: m["ds"] = 4;
6: m["ds"] = 10;
7: map<string,int>::iterator it = m.begin();8: while(it!=m.end())
9: {10: cout<<it->first<<" "<<it->second<<endl;
11: it++;12: }13: }
这种法式是通过重载[]来实现的,但是需要注意的是,这种法式和前两种有本质的区别,看下面的代码
m.insert(pair<string,int>("ds",5));
m.insert(pair<string,int>("ds",15));
当关键字相同的时候,不会改变他的值,也就是说在调用insert函数的时候,会检查,这个关键字是否存在了,如果存在,那么就不做任何操作。否则插入新的数据。
m["ds"] = 4;
m["ds"] = 10;
这种方式插入数据是不会做检查的,会直接在那个点上写上关键字和值,也就是说。ds项的值将是10.
3,数据遍历。
stl里的容器的遍历都是通过迭代器来遍历的。即便是用数组的方式,也是通过迭代器。数据遍历也有三种法式,1,向前迭代器,2,用反向迭代器,3,数组,第一种方式前面也就有说明。下面讲第二第三种,
反向迭代器的方式。
这样是以相反的法式输出的。
数组方式
void main( VOID )
{map<string,int> m;m["ds"] = 4;
m["as"] = 10;
m.insert(pair<string,int>("cs",5));m["bs"] = 123;
map<string,int>::iterator it = m.begin();for(int i=1;i<=m.size();i++){cout<<m[it->first]<<endl;//这里是用重载[]来得到value的。
it++;}}
4 .数据的查找(包括判定这个关键字是否在map中出现)
在这里我们将体会,map在数据插入时保证有序的好处。
要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。
这里给出三(2)种数据查找方法
第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了
第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器
#include <iostream>#include <fstream>#include <string>
#include <map>using namespace std;void main()
{//定义map 对象
map<string,int> word;//定义指针
map<string,int>::iterator it;//向word 插入元素 ("a",9)
word.insert (map<string,int>::value_type("a",9));//查找 键是"a"的元素,返回指向元素的指针。
it=word.find ("a");
//如果元素不存在,指针指向word.end().
if(it!=word.end ())
cout<<it->second<<endl; //输出元素的值
//查找 键是"a"的元素,
int result=word.count ("a");//如果键存在返回1,否则返回0
if(result)
cout<<word["a"]<<endl; //输出元素的值cout<<endl;}
5.数据清空,或判空,
清空数据用clear函数,判断数据是否是空用empty函数。
6.数据删除。
数据删除用erase函数,这个函数有3个重载函数,用的时候,可随机而用。注意用这个函数后,相关的迭代器将会失效。
三:pair是stl里(目前我知道的)定义的一个struct,在msdn上查到如下的信息。
template<class Type1, class Type2>
struct pair
{
typedef Type1 first_type;
typedef Type2 second_type
Type1 first;
Type2 second;
pair( );
pair(
const Type1& __Val1,
const Type2& __Val2
);
template<class Other1, class Other2>
pair(
const pair<Other1, Other2>& _Right
);
与之相关的是make_pair函数。是个模板函数。
template<class Type1, class Type2> pair<Type1, Type2> make_pair( Type1 _Val1, Type2 _Val2 );
四:关于map的迭代器,
对数据的插入,遍历,查找等操作,迭代器将不会失效,但是删除操作会失效。这与vector等序列式容器是不一样的。
五:效率
因为内部RB-TREE所以大多数的操作的时间复杂度都是O(logN),空间分析,在这些节点不保存数据的情况下就需要,左右孩子指针,指向父节点的指针,说明红黑的枚举值。
六:map的key的比较:
value_compare value_comp ( ) const;
其返回值是一个比较类的对象,这个类是map::value_compare,并且是map的一个内部类。
返回的这个对象可以用来通过比较两个元素的value来判决它们对应的key在map的位置谁在前面谁在后面。
下面是一个简单的例子,看一下就会更明白了:
#include <iostream>#include <map>using namespace std;int main ()
{map<char,int> mymap;map<char,int>::iterator it;pair<char,int> highest;mymap['x']=1001;mymap['y']=2002;mymap['z']=3003;cout << "mymap contains:\n";
highest=*mymap.rbegin(); // last element
it=mymap.begin();do {
cout << (*it).first << " => " << (*it).second << endl;
} while ( mymap.value_comp()(*it++, highest) );
return 0;
}
输出结果:
mymap contains:
x => 1001
y => 2002
z => 3003
解释一下,上面语句while里面的mymap.value_comp()(*it++, highest)在这样的条件下会返回true:
*it++对应的key在map中排在highest对应的key的前面时。