关于STL-MAP讲的很不错的一篇文章

一: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"] = 15;

这种方式插入数据是不会做检查的,会直接在那个点上写上关键字和值,也就是说。ds项的值将是15.

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的前面时。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值