STL--map学习笔记

Posted _Carrot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL--map学习笔记相关的知识,希望对你有一定的参考价值。

1、简介

MapC++的一个关联容器,它提供了很好的一对一的关系。(其中一个为关键字,每个关键字key只能在map中出现一次,第二个可称为关键字的值valuemap内部自建一颗红黑树(一种严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据是有序的。

2、功能

map自动建立key---value的对应,keyvalue可以是任意需要的类型

根据key的值快速查找记录,查找的复杂度基本是Log(N)

快速插入key---value记录

快速删除记录

根基key修改value记录

遍历所有记录

3、操作

使用map需要#include<map>头文件

 

  1. map最基本本的构造函数
map<string,int>mapstring;          map<int,string>mapint;
map<string,char>mapstring;       map<char,string>mapchar;
map<char,int>mapchar;          map<int,char>mapint;

插入操作

//用数组方式插入数据
#include<map>
#include<iostream>
using namespace std;
int main()
{
    map<int,string>mp;
    mp[1]="stu";
    mp[2]="den";
    mp[3]="t_one is";
    mp[4]=" a boy";
    map<int,string>::iterator it;
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->second;
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->first<<.<<it->second<<endl;
    return 0;
}
//用insert插入pair数据
#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    map<int,string>mp;
    mp.insert(pair<int,string>(1,"studentA"));
    mp.insert(pair<int,string>(2,"is "));
    mp.insert(pair<int,string>(3," a boy"));
    map<int,string>::iterator it;
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->second;
        cout<<endl;
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->first<<.<<it->second<<endl;
    return 0;
}
//用insert插入插入value_type数据
#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    map<int,string>mp;
    mp.insert(map<int,string>::value_type(1,"studentA "));
    mp.insert(map<int,string>::value_type(2,"studentB "));
    mp.insert(map<int,string>::value_type(3,"studentC "));
    map<int,string>::iterator it;
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->second;
        cout<<endl;
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->first<<.<<it->second<<endl;
    return 0;
}

以上三种用法虽然都可以实现数据插入,但也是有区别,第二种和第三种效果上是一样的,用insert函数插入数据在数据的插入上涉及到集合的唯一性这个歌概念,map种有关键字时,insert操作插入数据不了,但用数组方式就不同,他可以覆盖之前的关键字对应的值

 

  1.  *验证

    #include<map>
    #include<iostream>
    #include<cstring> 
    using namespace std;
    int main()
    {
        map<int,string>mp;
        map<int,string>::iterator it;
        mp.insert(map<int,string>::value_type(1,"studentA "));
        mp.insert(map<int,string>::value_type(2,"studentB "));    
        for(it=mp.begin();it!=mp.end();it++)            //遍历 
            cout<<it->first<<.<<it->second<<endl;    
            cout<<endl;    
        mp.insert(map<int,string>::value_type(1,"studentC "));            //用insert不能覆盖mapkey为1中value的值 
        mp.insert(map<int,string>::value_type(2,"studentD "));            //用insert不能覆盖mapkey为1中value的值 
        for(it=mp.begin();it!=mp.end();it++)            //遍历 
            cout<<it->first<<.<<it->second<<endl;
        return 0;
    }
    //数组形式
    #include<map>
    #include<iostream>
    using namespace std;
    int main()
    {
        map<int,string>mp;
        map<int,string>::iterator it;
        mp[1]="studentA";
        mp[2]="studentB";
        for(it=mp.begin();it!=mp.end();it++)            //遍历 
            cout<<it->first<<.<<it->second<<endl;
            cout<<endl;
        mp[1]="studentC";
        mp[2]="studentD";
        for(it=mp.begin();it!=mp.end();it++)            //遍历 
            cout<<it->first<<.<<it->second<<endl;
    
        return 0;
    }
        3、map
    的大小在往
        map

里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

        Int mpSize = mp.size();
    4、数据遍历

      第一种方法:应用前向迭代器:

#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    map<int,string>mp;
    map<int,string>::iterator it;
    mp.insert(map<int,string>::value_type(1,"studentA "));
    mp.insert(map<int,string>::value_type(2,"studentB "));
    mp.insert(map<int,string>::value_type(3,"studentC "));
    mp.insert(map<int,string>::value_type(4,"studentC "));    
    for(it=mp.begin();it!=mp.end();it++)            //遍历 
        cout<<it->first<<.<<it->second<<endl;    
    return 0;
}

      第二种方法:应用反向迭代器:

#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    map<int,string>mp;
    map<int,string>::reverse_iterator it;
    mp.insert(map<int,string>::value_type(1,"studentA "));
    mp.insert(map<int,string>::value_type(2,"studentB "));
    mp.insert(map<int,string>::value_type(3,"studentC "));
    mp.insert(map<int,string>::value_type(4,"studentC "));    
    for(it=mp.rbegin();it!=mp.rend();it++)            //遍历 
        cout<<it->first<<.<<it->second<<endl;    
    return 0;
}

     第三种:用数组形式

#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    map<int,string>mp;
    map<int,string>::iterator it;
    mp.insert(map<int,string>::value_type(1,"studentA "));
    mp.insert(map<int,string>::value_type(2,"studentB "));
    mp.insert(map<int,string>::value_type(3,"studentC "));
    mp.insert(map<int,string>::value_type(4,"studentD "));    
    int nsize=mp.size();
        //此处应注意,应该是 for(int nindex = 1; nindex <= nSize; nindex++)  
            //而不是 for(int nindex = 0; nindex < nSize; nindex++)          
    for(int nindex=1;nindex<=nsize;nindex++)            //遍历         
        cout<<nindex<<.<<mp[nindex]<<endl;
    return 0;
}

5、查找并获取map种的元素

一、count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1

二、find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。

查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()end()两个成员,

分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.

#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    int n;
    map<int,string>mp;
    map<int,string>::iterator it;
    mp.insert(map<int,string>::value_type(1,"studentA "));
    mp.insert(map<int,string>::value_type(2,"studentB "));
    mp.insert(map<int,string>::value_type(3,"studentC "));
    mp.insert(map<int,string>::value_type(4,"studentD "));    
    cin>>n;//要查找map的key值 
    it=mp.find(n);
    if(it!=mp.end())
        cout<<it->second;
        else cout<<"no find"<<endl;
    return 0;
}

 

6、map种删除元素

移除某个map中的元素

Iterator erase(iterator it);//通过一个条目对象删除

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

Iterator erase(iterator Key&key);//通过关键字删除

Clear()相当于 mp.erase(mp.begin(),mp.end());

#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
int main()
{
    map<int,string>mp;
    map<int,string>::iterator it;
    mp.insert(map<int,string>::value_type(1,"studentA "));
    mp.insert(map<int,string>::value_type(2,"studentB "));
    mp.insert(map<int,string>::value_type(3,"studentC "));
    mp.insert(map<int,string>::value_type(4,"studentD "));    
    //用迭代器删除1
/*    it=mp.find(1); 
    mp.erase(it);    
    for(map<int,string>::iterator it=mp.begin();it!=mp.end();it++)
        cout<<it->second<<endl; */

    //    利用关键字删除 
/*    int n=mp.erase(1);        //如果删除了会返回1,否则返回0      
    cout<<n<<endl;
    for(map<int,string>::iterator it=mp.begin();it!=mp.end();it++)
        cout<<it->second<<endl; */
        
    //用迭代器,成片的删除 
/*    mp.erase(mp.begin(),mp.end());
     //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合  
    for(map<int,string>::iterator it=mp.begin();it!=mp.end();it++)
        cout<<it->second<<endl;*/
        
    //测试 时将注释逐个去掉便可 
    return 0;
}

 

7、 map中的swap用法

map中的swap不是一个容器中的元素交换,而是两个容器所有元素的交换。

8、排序 map中的sort问题

 

map中的元素是自动按Key升序排序,所以不能对mapsort函数;

 

这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。

//第一种:小于号重载

#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
typedef struct Student
{
    int id;
    string stu_name;
    
    bool operator < (Student const& _A)const
    {
        if(id<_A.id)return true;
        if(id==_A.id)
            return stu_name.compare(_A.stu_name)<0;
            return false;
    }
} stu,*Pstu;
int main()
{
    int nsize;        //用学生信息映射分数
    map<stu ,int>mapstudent;
    map<stu ,int>::iterator it;
    stu  studentinfo;
    studentinfo.id=1;
    studentinfo.stu_name="student A";
    mapstudent.insert(map<stu,int>::value_type(studentinfo,90));
    studentinfo.id=2;
    studentinfo.stu_name="student B";
    mapstudent.insert(map<stu,int>::value_type(studentinfo,80));
    for(it=mapstudent.begin();it!=mapstudent.end();it++)
        cout<<it->first.id<< <<it->first.stu_name<< <<it->second<<endl;
    return 0;
}

 

//第二种:仿函数的应用,
#include<map>
#include<iostream>
#include<cstring> 
using namespace std;
typedef struct Student
{
    int id;
    string stu_name;
} stu,*Pstu;
class sort
{    
public:
    bool operator() (stu const &_A,stu const &_B)const
    {    
        if(_A.id < _B.id)
            return true;
        if(_A.id == _B.id)
            return _A.stu_name.compare(_B.stu_name)<0;
        return false;
    }    
};
int main()
{
    int nsize;        //用学生信息映射分数
    map<stu ,int,sort>mapstudent;
    map<stu ,int>::iterator it;
    stu  studentinfo;
    studentinfo.id=1;
    studentinfo.stu_name="student A";
    mapstudent.insert(pair<stu,int>(studentinfo,90));
    studentinfo.id=2;
    studentinfo.stu_name="student B";
    mapstudent.insert(pair<stu,int>(studentinfo,80));
    for(it=mapstudent.begin();it!=mapstudent.end();it++)
        cout<<it->first.id<< <<it->first.stu_name<< <<it->second<<endl;
    return 0;
}

mapvalue排序

原理说明http://blog.csdn.net/acidgl8757/article/details/17416439

#include<map>
#include<algorithm>
#include<iostream>
#include<cstring> 
#include<vector>
using namespace std;
typedef pair<string,int>PAIR;
struct cmp
{
    operator()(const PAIR& A,const PAIR& B)
    {
        return A.second<B.second;
    }
};
int main()
{
    map<string,int>stu_mp;
    stu_mp["student_A"]=90;
    stu_mp["student_B"]=78;
    stu_mp["student_C"]=92;
    stu_mp["student_D"]=97;    
    stu_mp.insert(make_pair("student E",99));
    vector<PAIR>stu_vec(stu_mp.begin(),stu_mp.end());
    sort(stu_vec.begin(),stu_vec.end(),cmp());
    
    map<string,int>::iterator it;
    cout<<"排序前"<<endl;
    for(it=stu_mp.begin();it!=stu_mp.end();it++)
        cout<<it->first<< <<it->second<<endl;
        
    cout<<"排序后"<<endl;
    for(int i=0;i!=stu_vec.size();i++)
        cout<<stu_vec[i].first<< <<stu_vec[i].second<<endl;
    return 0;
}

 

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的函数

 

 PS:QAQ此篇是学习map时参照别人的博客写的,大致思路按照原博客一样,QAQ我忘记原来的地址了,中间的代码自己重新写过,文章先写在word上,在放在博客上的....排版可能很丑,多多谅解,如有问题,欢迎提出,谢谢大家。

 

 

 

 

 

以上是关于STL--map学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

使用stl :: map和stl :: unordered_map对包含大量重复元素的数组数据进行排序

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

STL map 应用

cogs 615. 韩国明星 STL map

[C++STL]map容器用法介绍

STL map详细用法和make_pair函数