您的位置:首页 > 其它

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

2015-08-30 21:55 393 查看
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的函数。

转自:http://blog.sina.com.cn/s/blog_67001b350100kiro.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: