标准模板库(STL)学习探究之Maps容器

C++ Maps(关联容器) 
   map类定义了一个关联容器,并且在容器中使用唯一的关键字(任何两个元素的键都不相同)来映射相应的值。从本质上来说,关键字就是值的名字。在map对象中存储了一个值之后,就可以通过关键字来获得它。map对象是一系列关键字/值的匹配对。
   map的主要功能在于:只有你知道了一个值的关键字,就能够找到这个值。例如,定义一个map对象m,在该对象中使用人名作为关键字,并将每个人的电话号码存储为值。那么可以使用m[“张三”]表示张三的电话号码。从前面的例子可以看出map类有一个非常优越的特点:关联数组。在普通的数组中,索引是一个整数。而在关联数组中,索引是一个键,并且键可以是任意类型的,可以是String、double、int类型,甚至可以是一些用户定义的类。
    map和set的插入删除效率比用其他序列容器高,因为对于关联容器来说,不需要做内存拷贝和内存移动。map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。结构图可能如下:

            A
           / /
          B   C
         / / / /
        D  E F  G

因此插入的时候只需要稍做变换,把节点的指针指向新的节点就可以了。删除的时候类似,稍做变换后把指向删除节点的指针指向其他节点就OK了。这里的一切操作就是指针换来换去,和内存移动没有关系。
   每次insert之后,以前保存的iterator不会失效,因为iterator是指向节点的指针,内存没有变,指向内存的指针当然不会失效。

函数列表如下:
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的函数



constructors构造函数
explicit map(const Pred& comp = Pred(), const A& al = A());
map(const map& x);
map(const value_type *first, const value_type *last,
const Pred& comp = Pred(), const A& al = A());

运算符[]
为了添加元素,可使用下标算符[]:
map <string, string> addresses;
addresses["Paul W."]="paul@mail.com";
begin
语法: 
  iterator begin();
begin()函数返回一个迭代器指向map的第一个元素。
clear 
语法: 
  void clear();
clear()函数删除map中的所有元素。
count 
语法: 
  size_type count( const KEY_TYPE &key );
count()函数返回map中键值等于key的元素的个数。用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1.若key在map中存在,则返回1.

empty 
语法: 
  bool empty();
empty()函数返回真(true)如果map为空,否则返回假(false)。
end 
语法: 
  iterator end();
end()函数返回一个迭代器指向map的尾部。
equal_range 
Syntax: 
  pair equal_range( const KEY_TYPE &key );
equal_range()函数返回两个迭代器——一个指向第一个键值为key的元素,另一个指向最后一个键值为key的元素。
erase 
语法: 
  void erase( iterator pos );
  void erase( iterator start, iterator end );
  size_type erase( const KEY_TYPE &key );
erase()函数删除在pos位置的元素,或者删除在start和end之间的元素,或者删除那些值为key的所有元素。
find 
语法: 
  iterator find( const KEY_TYPE &key );
find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。
get_allocator 
语法: 
  allocator_type get_allocator();
get_allocator()函数返回map的配置器。
insert 
语法: 
  iterator insert( iterator pos, const pair<KEY_TYPE,VALUE_TYPE> &val );
  void insert( input_iterator start, input_iterator end );
  pair<iterator, bool> insert( const pair<KEY_TYPE,VALUE_TYPE> &val );
1.插入val到pos的后面,然后返回一个指向这个元素的迭代器。 
2.插入start到end的元素到map中。 
3.只有在val不存在时插入val。返回值是一个指向被插入元素的迭代器和一个描述是否插入的bool
因为map会排序,插入元素后,关键字将按升序排列,而与插入时的pos无关。
值。 
示例:
#include<iostream>
#include <fstream>
#include<map>
#include<string>
using namespace std;
void main()
{
    map<string,int> m,n;
    string key;int value;
    value=1;key="A12";
    m[key]=value;
    value=5;key="A3";
    m[key]=value;
    m["D5"]=4;
    m["A2"]=5;
    map<string,int>::iterator p=m.begin();//定义m对象的迭代器,并输出m中所有项
    p++;p++;
    m.insert(p,pair<string,int>("A1",7));
    m["B6"]=3;
    p=m.begin();
    for (int i=0; i<m.size(); i++)
   {
      cout <<p->first <<" "<<p->second <<endl;//first指向关键字,second指向值
      p++;
   }
   cout<<m.count("E")<<endl;
}
输出结果:
        A1 7
        A12 1
        A2 5
        A3 5
        B6 3
        D5 4
        0


请看下面代码:
#include <map>
#include <string>
#include <iostream>
Using namespace std;
void 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"));
}
    STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题.
第一种:小于号重载.
示例:
#include<iostream>
#include <fstream>
#include<map>
#include<string>
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; //学生信息
void main()
{
    map<StudentInfo,int>mapStudent;//关键字具有唯一性,不能两个内容相同的StudentInfo
    StudentInfo studentInfo;
    studentInfo.nID = 2;
    studentInfo.strName="student_one";
    mapStudent.insert(pair<StudentInfo,int>(studentInfo, 90));
    studentInfo.nID=1;
    studentInfo.strName="student_two";
    mapStudent.insert(pair<StudentInfo,int>(studentInfo, 80));
    map<StudentInfo,int>::iterator p=mapStudent.begin();
    cout<<p->first.strName<<endl;p++;
    cout<<p->first.strName<<endl;
}
输出结果:
        student_two
        student_one

第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载。
示例:
#include<iostream>
#include <fstream>
#include<map>
#include<string>
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;
          }
};
void main()
{
    map<StudentInfo,int,sort>mapStudent;
    StudentInfo studentInfo;
    studentInfo.nID = 2;
    studentInfo.strName="student_one";
    mapStudent.insert(pair<StudentInfo,int>(studentInfo,90));
    studentInfo.nID=1;
    studentInfo.strName="student_two";
    mapStudent.insert(pair<StudentInfo,int>(studentInfo,80));
    map<StudentInfo,int,sort>::iterator p=mapStudent.begin();
    cout<<p->first.strName<<endl;p++;
    cout<<p->first.strName<<endl;
}

key_comp 
语法: 
   key_compare key_comp();
   key_comp()函数返回一个比较key的函数。
   先说key_compare类,它是一个函数对象类型,这种类型的对象的行为象一个函数指针,指向的函数必须是接受两个key类型的值并返回一个bool类型的值。象这样:bool myCompare(const key_type& key1, const key_type& key2);然后你在定义map的时候,可以指定一个key_compare类型,在map的声明中第三个模板参数就是。如果你不指定,它有一个缺省的less<>可用。这个函数对象被map用于插入一个新元素时确定它的位置,即map通过调用这个函数,把新元素中的key和map里面已有元素的key进行比较,以找出新元素应该放在哪。

lower_bound 
语法: 
   iterator lower_bound(const Key& key);
   const_iterator lower_bound(const Key& key) const;
lower_bound()函数返回一个迭代器,指向map中键值<=key的第一个元素。If no such element exists, the function returns end(). 
例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3.

max_size 
语法: 
  size_type max_size();
max_size()函数返回map能够保存的最大元素个数。
rbegin 
语法: 
  reverse_iterator rbegin();
rbegin()函数返回一个指向map尾部的逆向迭代器。
rend 
语法: 
  reverse_iterator rend();
rend()函数返回一个指向map头部的逆向迭代器。
size 
语法: 
  size_type size();
size()函数返回map中保存的元素个数。
swap 
语法: 
  void swap( map &obj );
swap()交换obj和现map中的元素。
upper_bound 
语法: 
  iterator upper_bound( const KEY_TYPE &key );
upper_bound()函数返回一个迭代器,指向map中键值>key的第一个元素。
value_comp 
语法: 
  value_compare value_comp();
value_comp()函数返回一个比较元素value的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值