zoukankan      html  css  js  c++  java
  • map

     Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性
    map内部的实现自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能。
    下面举例说明什么是一对一的数据映射。比如一个班级中,每个学生的学号跟他的姓名就存在着一一映射的关系,这个模型用map可能轻易描述,
    很明显学号用int描述,姓名用字符串描述(本篇文章中不用char *来描述字符串,而是采用STL中string来描述),
    下面给出map描述代码:
    1.声明方式:
    Map<int, string> mapStudent;
    2.数据的插入
    在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:
    第一种:用insert函数插入pair数据
    Map<int, string> mapStudent;
    mapStudent.insert(pair<int, string>(1, “student_one”));
    第二种:用insert函数插入value_type数据
    mapStudent.insert(map<int, string>::value_type (1, “student_one”));
    第三种:用数组方式插入数据
    mapStudent[1] = “student_one”;
    3.            map的大小
    在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数:
    Int nSize = mapStudent.size();
    4.            数据的遍历
    第一种:应用前向迭代器
    map<int, string>::iterator iter;
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
    Cout<<iter->first<<”        ”<<iter->second<<end;
    第二种:应用反相迭代器
    map<int, string>::reverse_iterator iter;
    for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
    Cout<<iter->first<<”        ”<<iter->second<<end;
    第三种:用数组方式
    int nSize = mapStudent.size()
    for(int nIndex = 1; nIndex <= nSize; nIndex++)
    Cout<<mapStudent[nIndex]<<end;
    5.数据的查找(包括判定这个关键字是否在map中出现)
    这里给出三种数据查找方法
    第一种:用count函数来判定关键字是否出现,但是无法定位数据出现位置
    第二种:用find函数来定位数据出现位置它返回的一个迭代器,
    当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器
    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;
     }
    }
    第三种:这个方法用来判定数据是否出现
    Lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)
    Upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)
    例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3
    Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,程序说明
    mapPair = mapStudent.equal_range(2);
    if(mapPair.first == mapPair.second)
    cout<<”Do not Find”<<endl;
    6.数据的清空与判空
    清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map
    7.数据的删除
    这里要用到erase函数,它有三个重载了的函数
    迭代器删除
    iter = mapStudent.find(1);
    mapStudent.erase(iter);
    用关键字删除
    Int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0
    用迭代器,成片的删除
    一下代码把整个map清空
    mapStudent.earse(mapStudent.begin(), mapStudent.end());
    //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合
    #include <stdio.h>
    #include <string>
    #include <stdlib.h>
    #include <iostream>
    #include <map>
    #include <vector>
    using namespace std;
    typedef map<int, string> STRtemplatemap;
    int main()
    {
     STRtemplatemap Student;
     Student.insert(pair<int, string>(1, "student_one"));
     Student[2]="student_two";
     Student.insert(STRtemplatemap::value_type (3, "student_three"));
     for(STRtemplatemap::iterator iter=Student.begin();iter!=Student.end();iter++)
      cout << iter->second << endl;
     getchar();
     return 0;
    }
    8.其他一些函数用法
    这里有swap,key_comp,value_comp,get_allocator等函数,有兴趣的话可以自个研究

    简单例子:

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <map>
    using namespace std;

    typedef map <int ,string> templatemap;
    templatemap testmap;

    void main()
    {
     string data2="getid()";
     string data1="gethp()";
     string data="getmp()";
     testmap[1]=data;
     testmap[2]=data1;
     testmap[3]=data2;
     for (templatemap::iterator iter = testmap.begin();iter != testmap.end(); iter++)
     {
      cout<<iter->first<<" ";
      string data2=iter->second;
      for(int i=0;i<strlen(data2.c_str());i++)
      {
       cout<<data2[i];
      }
      cout<<endl;
     }
     templatemap::iterator itr = testmap.find(3);
     if(itr == testmap.end())
      return;
     string data4 = itr->second;
     cout<<3<<" ";
     for(int i=0;i<strlen(data4.c_str());i++)
     {
      cout<<data4[i];
     }
     cout<<endl;
     system("pause");
    }

    map 装struct

    #include <vector>
    #include <iostream>
    #include <map>
    using namespace std;
    struct Activity
    {
     int m_nStep;
     int m_nCount;
     Activity():
     m_nStep(1),m_nCount(0)
     {
     }
     Activity(const int nStep,const int nCount):
     m_nStep(nStep),m_nCount(nCount)
     {
     }
    };

    int main()
    {
     map <int ,Activity> test;
     test[1001] = Activity(1,10);
     cout<<"ID:"<<1001<<"步骤:"<<test[1001].m_nStep<<"人数:"<<test[1001].m_nCount<<endl;
     system("pause");
     return 0;
    }

    map最好不要在使用的时候删除东西

    #include <iostream>
    #include <map>

    using namespace std;
    typedef map<int, int> templatemap;

    templatemap AllScoreSort;
    void main()
    {
     for(int i=10000;i<10010;i++)
      AllScoreSort[i]=i;

     for (templatemap::iterator iter = AllScoreSort.begin(); iter!= AllScoreSort.end(); iter++)
     {
      int nRoleID = iter->first;
      int nScore = iter->second;
      if (10005 < nRoleID)
      {
       //AllScoreSort.erase(nRoleID);     //注意这行
       continue;
      }
      cout<<nRoleID<<" "<<nScore<<endl;
     }
     system("pause");
    }
    struct vector map嵌套使用

    #include <iostream>
    #include <vector>
    #include <map>
    using namespace std;
    struct LevelAwardItems
    {
     int m_ItemID;
     int m_Num;
     int m_KeyWorld;
    };
    typedef vector<LevelAwardItems> templateItem;
    templateItem m_VectItem;
    map <int, templateItem>m_MapLevelAward;

    void main()
    {
     for(int j=0;j<2;j++)
     {
      for(int i=0;i<2;i++)
      {
       LevelAwardItems item;
       item.m_ItemID = i;
       item.m_Num = i;
       item.m_KeyWorld = i;
       m_VectItem.push_back(item);
      }
      m_MapLevelAward[j] = m_VectItem;
      m_VectItem.clear();
     }
     for(int j = 0;j<2;j++)
     {
      m_VectItem = m_MapLevelAward[j];
      int nItemCout = m_VectItem.size();
      for(int k = 0;k <nItemCout;k++)
      {
       LevelAwardItems item;
       item = m_VectItem[k];
       cout<<item.m_ItemID<<endl;
       cout<<item.m_Num<<endl;
       cout<<item.m_KeyWorld<<endl;
      }
     }
     system("pause");
    }
    map map 嵌套使用

    #include<map>
    #include<iostream>
    #include <string>
    using namespace std;
    int main()
    {
     map<int,map<int,string> >multiMap; //对于这样的map嵌套定义,
     map<int, string> temp;    //定义一个map<int, string>变量,对其定义后在插入multiMap
     temp[90] = "hi";
     temp[100] = "maxi";
     multiMap[10] = temp;
     multiMap[10][80]="xiaoyu";
     multiMap[5][30]="xiaoma";
     map<int,map<int,string> >::iterator multitr;  // 以下是如何遍历本multiMap
     map<int,string>::iterator intertr;
     for(multitr=multiMap.begin();multitr!=multiMap.end();multitr++)
     {
      for(intertr= multitr ->second.begin(); intertr != multitr ->second.end(); intertr ++)
       cout<< multitr ->first<<" "<<intertr->first<<" ("<<intertr -> second <<")"<<endl;
     }
     system("pause");
     return 0;
    }

    stl之map erase方法的正确使用STL的map表里有一个erase方法用来从一个map中删除掉指令的节点
    eg:
    map<string,string> mapTest;
    typedef map<string,string>::iterator ITER;
    ITER iter=mapTest.find(key);
    mapTest.erase(iter);
    像上面这样只是删除单个节点,map的形为不会出现任务问题,
    但是当在一个循环里用的时候,往往会被误用,那是因为使用者没有正确理解iterator的概念.
    像下面这样的一个例子就是错误的写法,
    eg.
    for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)
    {
     cout<<iter->first<<":"<<iter->second<<endl;
     mapTest.erase(iter);
    }
    这是一种错误的写法,会导致程序行为不可知.究其原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。
    可以用以下方法解决这问题:
    正确的写法
    1.使用删除之前的迭代器定位下一个元素。STL建议的使用方式
    for(ITER iter=mapTest.begin();iter!=mapTest.end();)
    {
     cout<<iter->first<<":"<<iter->second<<endl;
     mapTest.erase(iter++);
    }
    2. erase() 成员函数返回下一个元素的迭代器
    for(ITER iter=mapTest.begin();iter!=mapTest.end();)
    {
     cout<<iter->first<<":"<<iter->second<<endl;
     iter=mapTest.erase(iter);
    }
    注意:
    map的earse应注意:
    map这种容器的下边访问和Vector等容器的下标访问有本质的区别。
    对于Vector容器,用aVector[i]访问第i个元素时,如果元素不存在,容器不会增加元素,
    而对于map,用aMap[key]
    访问键key对应的对象时,如果该键对应的对象存在,则返回该对象(这和Vector一样),但是,当键值为key的元素不存在时,容器会自动的增加一个pair,键为key,而值则为一个容器定义时指定的类型并默认初始化(即,如果该类型为基本类型,则初始化为0,比如本例中,aMap[1]的使用会产生一个pair,<1,NULL>,若该类型为类类型,则调用默认构造函数初始化之)
    显然,本例中,aMap[1]为NULL,后面的erase()不会执行,使得后面的
    插入语句aMap.insert(1,new A())键值冲突
    eg:如下代码会导致错误
    #include <iostream>
    #include <map>
    using namespace std;
    struct A
    {
     A(int i)
     {
      x=i;
     }
     int x;
    };
    int main()
    {
     map<int,A*> amap;
     if ( amap[1] != NULL )
      amap.erase(1);
     amap.insert(make_pair(1,new A(1)));
     amap.insert(make_pair(2,new A(2)));
     amap.insert(make_pair(3,new A(3)));
     return 0;
    }

    #include <string>
    #include <iostream>
    #include <map>
    using namespace std;

    class A
    {
    public:
     A(int _x,int _y)
     {
      x =_x;
      y =_y;
     }
     int x;
     int y;
    };
    typedef map<string,A*> stringAMap;
    int main()
    {
     stringAMap map1;
     A* a = new A(100,200);
     map1.insert(make_pair("韦宇浩",a));
     map1.insert(make_pair("陆一峰",new A(200,300)));
     stringAMap::iterator pos = map1.find("韦宇浩");
     if (pos != map1.end())
     {
      //delete(pos->second);
      map1.erase(pos);
     }
     cout << a->x<<endl;
     system("pause");
     return 0;
    }

     stl map高效遍历删除的方法

    for(;iter!=mapStudent.end();)
    {
         if((iter->second)>=aa)
         {
             //满足删除条件,删除当前结点,并指向下面一个结点
                  mapStudent.erase(iter++);
         }
         else
         {
         //条件不满足,指向下面一个结点
         iter++;
         }
    }
    点击打开链接

  • 相关阅读:
    Java 工程转 C#
    初涉Linux ----------> 打造自己的 Vim IDE
    初涉Linux ----------> Ubuntu15.04的安装与美化
    没学过CSS等前端的我,也想美化一下自己的博客
    作为程序员之 Vim(一)
    win7升win10,初体验
    作为程序员之正则表达式
    数据库系统原理
    Mysql数据库笔记
    我的个人常用快捷键
  • 原文地址:https://www.cnblogs.com/byfei/p/14104743.html
Copyright © 2011-2022 走看看