C++ STL学习笔记一----map

                                                                                  C++ STL学习笔记一----map

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

1、map简介

map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改实值,而不能修改key。

2、map的功能

自动建立Key - value的对应。key 和 value可以是任意你需要的类型。

根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。

快速插入Key -Value 记录。

快速删除记录

根据Key 修改value记录。

遍历所有记录。

3、使用map

使用map得包含map类所在的头文件

#include <map>  //注意,STL头文件没有扩展名.h

map对象是模板类,需要关键字和存储对象两个模板参数:

std:map<int,string> personnel;

这样就定义了一个用int作为索引,并拥有相关联的指向string的指针

4、map的构造函数

 

    map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:

       map<string , int >mapstring;         map<int ,string >mapint;
   map<sring, char>mapstring;         map< char ,string>mapchar;
   map<char ,int>mapchar;            map<int ,char >mapint;

map<int, string> mapStudent;


5、     数据的插入


在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:

方法一:

       用insert插入pair的数据

#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
       map<int, string> mapStudent;//pair<int,string>p;p=make_pair(v1,v2);<span style="color: rgb(255, 0, 0); background-color: rgb(240, 248, 255); font-family: Arial; font-size: 13px; "> </span>  
       mapStudent.insert(make_pair(1, "student_one"));  
       mapStudent.insert(make_pair(2, "student_two"));  
       mapStudent.insert(make_pair(3, "student_three"));  
       map<int, string>::iterator  iter;  
       for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
       {  
          cout<<iter->first<<"  "<<iter->second<<endl;  
       }  
}  



方法二:用insert函数插入value_type数据

#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
       map<int, string> mapStudent;  
       mapStudent.insert(map<int, string>::value_type (1, "student_one"));  
       mapStudent.insert(map<int, string>::value_type (2, "student_two"));  
       mapStudent.insert(map<int, string>::value_type (3, "student_three"));  
       map<int, string>::iterator  iter;  
       for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
       {  
           cout<<iter->first<<" "<<iter->second<<endl;  
       }  
} 


第三种:用数组方式插入数据


mapString[key] = value;

#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
       map<int, string> mapStudent;  
       mapStudent[1] =  "student_one";  
       mapStudent[2] =  "student_two";  
       mapStudent[3] =  "student_three";  
       map<int, string>::iterator  iter;  
       for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
       {  
          cout<<iter->first<<"   "<<iter->second<<endl;  
       }  
}  



6.map的大小

在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:
 
  int size = mapStudent.size();

7.map数据的遍历
  
    (1).应用迭代器

 正向迭代器:

    
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
       {  
          cout<<iter->first<<"   "<<iter->second<<endl;  
       }  


反向迭代器:
  
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
       map<int, string> mapStudent;  
       mapStudent.insert(pair<int, string>(1, "student_one"));  
       mapStudent.insert(pair<int, string>(2, "student_two"));  
       mapStudent.insert(pair<int, string>(3, "student_three"));  
       map<int, string>::reverse_iterator  iter;  
       for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)  
       {  
          cout<<iter->first<<"   "<<iter->second<<endl;  
       }  
} 





(2)数组方式

    cout<< mapStudent[key]

     

8.数据的查找

      使用迭代器的find函数,find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器

  

    mapStudent.find(value);

#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
       map<int, string> mapStudent;  
       mapStudent.insert(pair<int, string>(1, "student_one"));  
       mapStudent.insert(pair<int, string>(2, "student_two"));  
       mapStudent.insert(pair<int, string>(3, "student_three"));  
       map<int, string>::iterator iter;  
       iter = mapStudent.find(1);  
       if(iter != mapStudent.end())  
      {  
           cout<<"Find, the value is "<<iter->second<<endl;  
       }  
       Else  
       {  
           cout<<"Do not Find"<<endl;  
       }  
}  




        

9.数据的清空与判空

清空map中的数据可以用clear()函数

判定map中是否有数据可以用empty()函数,它返回true则说明是空map

10.数据的删除

   erase函数,有三个重载
  
   iterator erase(iterator it); //通过一个条目对象删除 

   iterator erase(iterator first, iterator last); //删除一个范围 

   size_type erase(const Key& key); //通过关键字删除 
  
   clear()就相当于 enumMap.erase(enumMap.begin(), enumMap.end());
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
       map<int, string> mapStudent;  
       mapStudent.insert(pair<int, string>(1, "student_one"));  
       mapStudent.insert(pair<int, string>(2, "student_two"));  
       mapStudent.insert(pair<int, string>(3, "student_three"));  
       //如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好  
       //如果要删除1,用迭代器删除  
       map<int, string>::iterator iter;  
       iter = mapStudent.find(1);  
       mapStudent.erase(iter);  
       //如果要删除1,用关键字删除  
       int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0  
       //用迭代器,成片的删除  
       //一下代码把整个map清空  
       mapStudent.earse(mapStudent.begin(), mapStudent.end());  
       //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合  
     //自个加上遍历代码,打印输出吧  
}  




11.排序

 Map中的元素是自动按key升序排序,所以不能对map用sort函数:
   排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题
第一种:小于号重载,程序举例
#include <map>
#include <string>
#include <iostream>
using namespace std;
typedef struct tagStudentInfo
{
       int      nID;
       string   strName;
       bool operator < (tagStudentInfo const& _A) const
       {
              //这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序
              if(nID < _A.nID)  return true;
              if(nID == _A.nID) return strName.compare(_A.strName) < 0;
              return false;
       }
}StudentInfo, *PStudentInfo;  //学生信息
int main()
{
       //int nSize;
       //用学生信息映射分数
       map<StudentInfo, int>mapStudent;
       map<StudentInfo, int>::iterator iter;
       StudentInfo studentInfo;
       studentInfo.nID = 1;
       studentInfo.strName = "student_one";
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));
       studentInfo.nID = 2;
       studentInfo.strName = "student_two";
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));
       for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)
         cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;
}




第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明
#include <map>
#include <string>
#include <iostream>
using namespace std;
typedef struct tagStudentInfo
{
       int      nID;
       string   strName;
}StudentInfo, *PStudentInfo;  //学生信息
class sort
{
       public:
       bool operator() (StudentInfo const &_A, StudentInfo const &_B) const
       {
              if(_A.nID < _B.nID) return true;
              if(_A.nID == _B.nID) return _A.strName.compare(_B.strName) < 0;
              return false;
       }
};
int main()
{
       //用学生信息映射分数
       map<StudentInfo, int, sort>mapStudent;
       StudentInfo studentInfo;
       studentInfo.nID = 1;
       studentInfo.strName = "student_one";
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));
       studentInfo.nID = 2;
       studentInfo.strName = "student_two";
       mapStudent.insert(pair<StudentInfo, int>(studentInfo,80));
      map<StudentInfo, int>::iterator iter;
       for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)
         cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;
}

12. map中 swap的用法:
  Map中的swap不是一个容器中的元素交换,而是两个容器交换;
 
  #include <map>
  #include <iostream>
  using namespace std;
  int main( )
  {
      map <int, int> m1, m2, m3;
      map <int, int>::iterator m1_Iter;
      m1.insert ( pair <int, int>  ( 1, 10 ) );
      m1.insert ( pair <int, int>  ( 2, 20 ) );
      m1.insert ( pair <int, int>  ( 3, 30 ) );
      m2.insert ( pair <int, int>  ( 10, 100 ) );
      m2.insert ( pair <int, int>  ( 20, 200 ) );
      m3.insert ( pair <int, int>  ( 30, 300 ) );
   cout << "The original map m1 is:";
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout << " " << m1_Iter->second;
      cout   << "." << endl;
   // This is the member function version of swap
   //m2 is said to be the argument map; m1 the target map
   m1.swap( m2 );
   cout << "After swapping with m2, map m1 is:";
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout << " " << m1_Iter -> second;
      cout  << "." << endl;
   cout << "After swapping with m2, map m2 is:";
   for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ )
      cout << " " << m1_Iter -> second;
      cout  << "." << endl;
   // This is the specialized template version of swap
   swap( m1, m3 );
   cout << "After swapping with m3, map m1 is:";
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout << " " << m1_Iter -> second;
      cout   << "." << endl;
}


13.value_comp()

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

总结:
   map的基本操作函数:
      C++ Maps是一种关联式容器,包含“关键字/值”对
      begin()          返回指向map头部的迭代器
      clear()          删除所有元素
      count()           返回指定元素出现的次数
      empty()          如果map为空则返回true
      end()            返回指向map末尾的迭代器
      equal_range()      返回特殊条目的迭代器对
      erase()           删除一个元素
      find()           查找一个元素
      get_allocator()     返回map的配置器
      insert()          插入元素
      key_comp()        返回比较元素key的函数
      lower_bound()      返回键值>=给定元素的第一个位置
      max_size()        返回可以容纳的最大元素个数
      rbegin()          返回一个指向map尾部的逆向迭代器
      rend()           返回一个指向map头部的逆向迭代器
      size()            返回map中元素的个数
      swap()            交换两个map
      upper_bound()      返回键值>给定元素的第一个位置
      value_comp()       返回比较元素value的函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值