map使用积累

1.从map中读取元素而又不插入该元素

find操作返回指向元素的迭代器,如果该元素不存在,则返回end迭代器:

int occurs = 0 ;

map<string, int>::iterator it = word_count.find("foobar") ;

if (it != word_count.end())

{

occurs = it->second ;

}

2.人工定制的map排序方法:


3.定义map的排序方式:

typedef std::multimap<double,CStdString,less<double>>ADPRIORITY_MAP;

4.       排序

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

第一种:小于号重载,程序举例

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

       Int      nID;

       String   strName;

}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;

 

}

以上程序是无法编译通过的,只要重载小于号,就OK了,如下:

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;  //学生信息

第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

       Int      nID;

       String   strName;

}StudentInfo, *PStudentInfo;  //学生信息

 

Classs 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));

}

5.  另外

由于STL是一个统一的整体,map的很多用法都和STL中其它的东西结合在一起,比如在排序上,这里默认用的是小于号,即less<>,如果要从大到小排序呢,这里涉及到的东西很多,在此无法一一加以说明。

还要说明的是,map中由于它内部有序,由红黑树保证,因此很多函数执行的时间复杂度都是log2N的,如果用map函数可以实现的功能,而STL  Algorithm也可以完成该功能,建议用map自带函数,效率高一些。

下面说下,map在空间上的特性,否则,估计你用起来会有时候表现的比较郁闷,由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑的,相当于平衡二叉树中的平衡因子),我想大家应该知道,这些地方很费内存了吧,不说了……

6.

三种插入方式:

   2.1.1用insert方法插入pair对象:
   enumMap.insert(pair<int, Cstring>(1, “One”));
   2.1.2 用insert方法插入value_type对象:
   enumMap.insert(map<int, Cstring>::value_type (1, “One”));
   2.1.3 用数组方式插入值:
   enumMap[1] = "One";
  enumMap[2] = "Two";
  ......

  这样非常直观,但存在一个性能的问题。插入2时,先在enumMap中查找主键为2的项,没发现,然后将一个新的对象插入enumMap,键是2,值是一个空字符串,插入完成后,将字符串赋为"Two"; 该方法会将每个值都赋为缺省值,然后再赋为显示的值,如果元素是类对象,则开销比较大。用前两种方法可以避免开销。

7.

从map中删除元素

   移除某个map中某个条目用erase()
  该成员方法的定义如下:
  1.iterator erase(iterator it); //通过一个条目对象删除
  2.iterator erase(iterator first, iterator last); //删除一个范围
  3.size_type erase(const Key& key); //通过关键字删除
   清除所有的元素clear()
  clear()就相当于 enumMap.erase(enumMap.begin(), enumMap.end());

8.Map中的元素是自动按key升序排序,所以不能对map用sort函数

9.map的取值操作

map <string, int> word_count; // empty map
// insert default initialzed element with key Anna; then assign 1
to its value
word_count["Anna"] = 1;
将发生以下事情:
1). 在 word_count 中查找键为 Anna 的元素,没有找到。
2). 将一个新的键-值对插入到 word_count 中。它的键是 const string 类型
的对象,保存 Anna。而它的值则采用值初始化,这就意味着在本例中值为 0。
3). 将这个新的键-值对插入到 word_count 中。
4). 读取新插入的元素,并将它的值赋为 1。
使用下标访问 map 与使用下标访问数组或 vector 的行为截
然不同:用下标访问不存在的元素将导致在 map 容器中添加一
个新元素,它的键即为该下标值。
如同其他下标操作符一样,map 的下标也使用索引(其实就是键)来获取该
键所关联的值。如果该键已在容器中,则 map 的下标运算与 vector 的下标运
算行为相同:返回该键所关联的值。只有在所查找的键不存在时,map 容器才为
该键创建一个新的元素,并将它插入到此 map 对象中。此时,所关联的值采用
值初始化:类类型的元素用默认构造函数初始化,而内置类型的元素初始化为 0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值