C++深入分析STL中map容器的使用
1、map容器
map是C++ STL的一个关联容器,它提供一对一的数据处理能力。其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int、double 等)、使用结构体或类自定义的类型。
第一个可以称为关键字(key);
第二个可能称为该关键字的值(value);
该容器存储的都是 pair<const K, T> 类型(其中 K 和 T 分别表示键和值的数据类型)的键值对元素。
使用 map 容器存储的各个键值对,键的值既不能重复也不能被修改。换句话说,map 容器中存储的各个键值对不仅键的值独一无二,键的类型也会用 const 修饰,这意味着只要键值对被存储到 map 容器中,其键的值将不能再做任何修改。
2、map容器原理
map容器的实现是自建了一颗红黑树,这颗树具有对数据自动排序的功能,在map内部所有的数据都是有序的
3、map容器函数接口
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的函数
#include<map>
map<key, value> m;//创建一个名为m的空map对象,其键和值的类型分别为key和value。
map<key, value> m(m2);//创建m2的副本m,m与m2必须有相同的键类型和值类型。
map<key, value> m(b,e);//创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本,元素的类型必须能转换为pair
//查
m.count(k);// 返回m中键值等于k的元素的个数。
m.find(k);// 如果m中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回结束游标end()。
//删
//迭代器刪除
iter = m.find("123");
m.erase(iter);
//用关键字刪除
int n = m.erase("123"); //如果刪除了會返回1,否則返回0
//用迭代器范围刪除 : 把整个map清空
m.erase(m.begin(), m.end());
//等同于m.clear()
m.erase(k); // 删除m中键为k的元素,返回size_type类型的值,表示删除元素的个数。
m.erase(p); // 从m中删除迭代器p所指向的元素,p必须指向m中确实存在的元素,而且不能等于m.end(),返回void类型。
m.erase(iterator first, iterator last); // 删除一个范围,返回void类型。
//插入
// 第一种 用insert函數插入pair
m.insert(pair<int, string>(000, "student_zero"));
// 第二种 用insert函数插入value_type数据
m.insert(map<int, string>::value_type(001, "student_one"));
// 第三种 用"array"方式插入
m[123] = "student_first";
m[456] = "student_second";
m.insert(e) ;
e是一个用在m上的value_type类型的值。如果键e.first不在m中,则插入一个值为e.second的新元素;如果该键在m中已存在,那么不进行任何操作。该函数返回一个pair类型对象,包含指向键为e.first的元素的map迭代器,以及一个bool类型的对象,表示是否插入了该元素。
m.insert(beg, end);
beg和end是标记元素范围的迭代器,对于该范围内的所有元素,如果它的键在m中不存在,则将该键及其关联的值插入到m。 返回void类型。
m.insert(iter, e);
e是value_type类型的值,如果e.first不在m中,则创建新元素,并以迭代器iter为起点搜索新元素存储的位置,返回一个迭代器,指向m中具有给定键的元素。 在添加新的map元素时,使用insert成员可避免使用下标操作符带来的副作用:不必要的初始化。
//在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:int nSize = mapStudent.size();
pair<map<int,string>::iterator,bool>Insert_Pair;
Insert_Pair=mapStudent.insert(map<int,string>::value_type(1, "student_one"));
我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。
4、使用示例
(1)插入
- insert 函数插入 pair 数据
std::map < int , std::string > mapPerson;
mapPerson.insert(pair < int,string > (1,"Jim"));
- insert 函数插入 value_type 数据
mapPerson.insert(std::map < int, std::string > ::value_type (2, "Tom"));
- 用数组方式插入数据
mapPerson[3] = "Jerry";
(2)遍历
前向迭代器
std::map < int ,std::string > ::iterator it;
std::map < int ,std::string > ::iterator itEnd;
it = mapPerson.begin();
itEnd = mapPerson.end();
while (it != itEnd)
{
cout<<it->first<<' '<<it->second<<endl;
it++;
}
反向迭代器
std::map < int, string > ::reverse_iterator iter;
for(iter = mapPerson.rbegin(); iter != mapPerson.rend(); iter++)
cout<<iter->first<<" "<<iter->second<<endl;
数组形式
mapPerson.insert(std::map<int, std::string>::value_type (1, "Tom"));
mapPerson[2] = "Jim";
mapPerson[3] = "Jerry";
int nSize = mapPerson.size();
for(int n = 1; n <= nSize; n++)
qDebug()<<QString::fromStdString(mapPerson[n]);
(3)查找
三种数据查找方法
第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了
第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,
分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.
通过map对象的方法获取的iterator数据类型是一个std::pair对象,包括两个数据 iterator->first和 iterator->second分别代表关键字和存储的数据。
map<int ,string > ::iterator l_it;;
l_it = maplive.find(112);
if(l_it == maplive.end())
cout<<"we do not find 112"<<endl;
else cout<<"wo find 112"<<endl;
第三种:这个方法用来判定数据是否出现,是显得笨了点,
lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)
upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)
例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,
而upper-bound(2)的话,返回的就是3
Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[3] = "student_three";
mapStudent[5] = "student_five";
map<int, string>::iterator iter;
iter = mapStudent.lower_bound(1);
//返回的是下界1的迭代器
cout<<iter->second<<endl;
iter = mapStudent.lower_bound(2);
//返回的是下界3的迭代器
cout<<iter->second<<endl;
iter = mapStudent.lower_bound(3);
//返回的是下界3的迭代器
cout<<iter->second<<endl;
iter = mapStudent.upper_bound(2);
//返回的是上界3的迭代器
cout<<iter->second<<endl;
iter = mapStudent.upper_bound(3);
//返回的是上界5的迭代器
cout<<iter->second<<endl;
pair<map<int, string>::iterator, map<int, string>::iterator> mappair;
mappair = mapStudent.equal_range(2);
if(mappair.first == mappair.second)
cout<<"Do not Find"<<endl;
else
cout<<"Find"<<endl;
mappair = mapStudent.equal_range(3);
if(mappair.first == mappair.second)
cout<<"Do not Find"<<endl;
else
cout<<"Find"<<endl;
return 0;
}
(4)删除
iterator erase(iterator it) ;//通过一个条目对象删除
iterator erase(iterator first,iterator last); //删除一个范围
size_type erase(const Key&key); //通过关键字删除
clear();//就相当于enumMap.erase(enumMap.begin(),enumMap.end());
到此这篇关于C++深入分析STL中map容器的使用的文章就介绍到这了,更多相关C++STL中map容器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341