map映照容器

爷,独闯天下 提交于 2020-02-03 13:41:04

    set和map都是泛型库对二叉树的一个泛化。

一、map的相关原理

    map映照容器所处理的元素数据,与数据库中的具有键值的记录非常相似,由一个键值和其它若干个数据(映照数据组成),键值和映照数据之间,可建立一个数学上的映照关系。容器的数据结构是采用红黑树进行管理,元素值不允许重复,所使用的节点元素的比较函数,只对元素的键值进行比较,元素的各个数据项可通过键值检索。

数据构成如图所示:

(一个pair对象)

如图所示为map容器的一个元素的数据组成,可通过pair封装成一个结构对象。map容器所要做的,就是将这个pair对象插入到红黑树中,完成一个元素的添加,同时,也要提供一个仅使用键值进行比较的函数对象,将它传递给红黑树。由此,就可以利用红黑树的操作,map元素数据插入到二叉树的正确位置,也可以根据键值进行元素的删除和检索。

 

map通过内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在std map内部所有的数据都是有序的。

二、map的应用

1、创建

(2)map()

利用默认的less<T>函数对象和内存分配器,创建一个没有任何元素的map对象。

map<char,int,greater<char> >m; //创建空map对象,元素的键值类型为char,元素的映照数据类型为int,键值的比较函数对象为greater<char>.

(2)map(const key_compare& comp); 

//指定个函数对象来创建map对象,内存分配器为默认值。

//定义字符串比较函数对象strLess 

struct strLess{

bool operator()(const char* s1,const char* s2) const

  {

   return strcmp(s1,s2)<0;

  }

};

//创建map容器对象m 

map<const char*, int> m(strLess()); 

(3)map(const map&)

拷贝构造函数,用一个map容器的元素和比较函数,拷贝生成一个新的map容器对象。

//map<int,char*> m1;

map<int,char*> m2(m1);

(4)map(InputIterator first, InputIterator last);

用迭代器区间[first, last)所指的数据,作为map容器的元素(包括键值和映照数据),创建一个map容器对象。例如,下面代码使用数组pairArray的5个pair对象,创建map容器对象m。

pair<const int,char> p1(1,'a');

pair<const int,char> p1(2,'b');

pair<const int,char> p1(3,'c');

pair<const int,char> p1(4,'d');

pair<const int,char> p1(5,'e');

pair<const int,char> pairArray[]={p1,p2,p3,p4,p5};

map<const int,char> m(pairArray,pairArray+5) 

(5)map(InputIterator first, InputIterator last, const key_compare& comp);

用迭代器区间[first, last)所指的数据和comp函数对象,创建一个map对象。例如,下面代码使用greater<int>函数对象,取代默认的less<int>,创建一个map对象m。 

map<const int, char,greater<const int> > m(pairArray, pairArray+5, greater<const int>());  

2、元素的插入

(1)用insert函数

    pair<iterator, bool> insert(const value_type& v) 

将元素v(包括键值和映照数据)插入 map 容器,重复的v值不被插入。返回一个pair配对对象,提供所插入元素的迭代器位置和true/false插入成功标志。 

    iterator insert(iterator position, const value_type& v) 

将元素 v(包括键值和映照数据)插入 map 容器,参数 position 只是提示可在 position位置之前插入v,所返回的插入位置视实际情况而定,不一定能在position位置前插入。

    void insert(InputIterator first, InputIterator last) 

将迭代器区间[first, last)所指的数据作为容器元素(包括键值和映照数据),插入到map容器中。

(2)还可用以map容器的数据操作[]显示地为不同键值赋予内容(映照数据),不过此时无法检测是否插入成功。

#include "map"

#include "iostream"

int main()

{

using namespace std;

map<const char*,float> m;

m["apple"]=3.6f;

m["orange"]=3.2f;

m["banana"]=1.8f;

cout<<"苹果是:"<<m["apple"]<<"yuan/jin\n";

cout<<"桔子是:"<<m["orange"]<<"yuan/jin\n";

cout<<"香蕉是:"<<m["banana"]<<"yuan/jin\n";

return 1;

}

3、元素的删除

(1)与 set 集合容器一样,map 映照容器的删除函数,可删除某个迭代器位置上的元素、等于某键值的元素、一个迭代器区间上的元素和容器中的所有元素。 

(1)void erase(iterator position) 

删除position所指的元素。 

(2)size_type erase(const key_type& k) 

删除键值为k的元素。对map容器来说,此函数总是返回值1,因为map容器不会出现键值重复的元素值。 

(3)void erase(iterator first, iterator last) 

删除map迭代器区间[first, last)上的所有元素。 

(4)void clear() 

删除map容器的所有元素。

4、元素的遍历访问

    除了利用键值的数组方式来访问元素外,更一般可使用map容器的迭代器进行访问,通常需要用 begin 和 end 函数找出遍历开始的首元素和结束元素,然后通过迭代器的“++”和“*”操作,读取容器元素。以下是map容器的begin和end函数原型,分别返回指向首尾元素的迭代器位置。 

(1)iterator begin() 

(2)iterator end() 

#include "map"

#include "string"

#include "iostream"

using namespace std;

struct StudentInfo{

string name;

int year;

string addr;

};

struct StudentRecord{

int id;

StudentInfo sf;

};

int main()

{

StudentRecord srArray[]={

   {1,"Ia",21,"BeiJing"},

   {2,"Ya",22,"ShangHai"},

   {3,"Ta",23,"GuangXhou"}

};

map<int,StudentInfo> m;

for(int j=0;j<3;j++)

 m[srArray[j].id]=srArray[j].sf;

map<int,StudentInfo>::iterator i,iend;

iend=m.end();

cout<<"S_Id "<<"Name "<<"Age "<<"Addr "<<endl;

for(i=m.begin();i!=iend;i++)

 cout<<(*i).first<<" "

  <<(*i).second.name<<" "

  <<(*i).second.year<<" "

  <<(*i).second.addr<<" "

  <<endl;

return 1; 

}

5、反向遍历

利用map容器定义的反向迭代器reverse_iterator和const_reverse_iterator,及获取反向首尾元素的rbegin和rend函数,可完成map容器元素的反向遍历。 

(1)reverse_iterator rbegin() 

(2)reverse_iterator rend() 

6、元素的搜索

利用map容器提供的find函数,可搜索出具有某一键值的元素。map容器的元素键值是唯一的。find函数返回的迭代器值为搜索到的元素位置,如果该元素不存在,则返回一个end结束元素位置。 

iterator find(const key_type& k) const 

7、其它诸如size,swap,lower_bound等,可参见前面的总论部分:

http://blog.163.com/zhoumhan_0351/blog/static/39954227201022644534780
8、下面一个例子

#include "map"

#include "string"

#include "iostream"

using namespace std;

class StudentRecord{

public:

 struct StudentInfo{

 string name;

 int year;

 string addr;

 };

 StudentRecord(int id_,string name_,int year_,string addr_){

 id=id_;

 sf.name=name_;

 sf.year=year_;

 sf.addr=addr_;

 }

 int id;

 StudentInfo sf;

};

int main()

{

typedef map<int,StudentRecord::StudentInfo> studentmap;

studentmap m;

pair<studentmap::iterator,bool> p;

StudentRecord student1=StudentRecord(1,"JH",21,"BJ");

pair<int,StudentRecord::StudentInfo> pairStudent1(student1.id,student1.sf);

p=m.insert(pairStudent1);

//pair<iterator, bool> insert(const value_type& x);  

if(!p.second)

 cout<<"Failed"<<endl

     <<student1.id<<" "

  <<student1.sf.name<<" "

  <<student1.sf.year<<" "

  <<student1.sf.addr<<" "

  <<endl;

StudentRecord student2=StudentRecord(2,"JH2",22,"TJ");

pair<int,StudentRecord::StudentInfo> pairStudent2(student2.id,student2.sf);

p=m.insert(pairStudent2);

if(!p.second)

 cout<<"Failed"<<endl

     <<student2.id<<" "

  <<student2.sf.name<<" "

  <<student2.sf.year<<" "

  <<student2.sf.addr<<" "

  <<endl;

studentmap::iterator i=m.find(2);

cout<<"class ID 2's record is:\n"

    <<(*i).first<<" "

 <<(*i).second.name<<" "

 <<(*i).second.year<<" "

 <<(*i).second.addr<<" "

 <<endl;

return 1;

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!