C++关联容器总结一

关联容器

关联容器: 通过键(key)储存与读取元素
顺序容器: 通过元素在容器中的位置顺序储存,访问

关联容器类型
map 关联数组:元素通过键来存储和读取
set 大小可变的集合,支持通过键实现的快速读取, 具有集合的性质
multimap 支持同一个键多次出现的 map 类型
multiset 支持同一个键多次出现的 set 类型

与关联容器相关的pair
pair:一种类模板, 定义在头文件utility中
T1,T2为元素类型, 可以是容器或者类,pair类型
pair< T1,T2 >p , p对象当前具有两个属性T1,T2
访问pair对象直接使用p.first , p.second 访问其数据成员

pair<int, pair<string,int> >p1(1,"hello",1);
//注意p1前面两个大于号之间要留有空格,防止编译时看成位运算
//p1具有三个属性(int string int)
cout<<p1.first<<p1.second.first<<p1.second.second;
//first,second分别对应着p1对象的两个数据成员

关联容器
关联容器具有顺序容器大部分操作 ,但没有front, push_front, pop_front, back, push_back, pop_back,assign, resize操作
具有以下构造函数:

  • C< T >c;
  • C< T >c1(c2);
  • C< T >c(b,e)

关联容器不能通过容器大小来定义(即C< T >c(n) ), 当关联容器通过大小来定义, 就无法确定初始化的那个对象需要采用哪个值或哪些值来初始化,若采用0来初始化这n个对象时将造成多个键重复,这样就无法知道键所对应的值是哪个

map类型
map: 关联数组(采用key获取值与数组采用下标获取值一致)
map构造函数

  • map< k,v >m; 创建空的map对象, 其键与值为k, v
  • map< k,v >m(m2); 创建m2的副本, m2与m必须具有相同的key,value
  • map< k,v >m(b,e); m储存迭代器b,e之间元素的副本, 元素必须能转换为pair< const k, v >

map迭代器进行解引用的时候将产生pair对象

//m为存在键值的元素
map<string,int>::iterator iter=m.begin();
cout<<iter->first<<iter->second;

键类型约束问题
map中key不但具有类型, 还具有一个相关的比较函数,比较函数必须在键类型上定义严格弱排序,因此在map元素插入的过程中元素会依据键的大小关系进行排序,键值类型必须定义”<”操作符
详情观看转载
https://blog.csdn.net/qq_29344757/article/details/7869
例:
map对象可以使用vector< int >::iterator为key, iterator对象内置弱排序(iter可进行大小,加减比较操作)
map对象不可以使用list< int >::iterator为key, iterator对象内不能进行弱排序(iter只具有”==”与”!=”操作)

采用下标访问map对象

int main(){
    map<string,int>m;
    m["hello"]=1;
    m["world"]=2;
    map<string,int>::iterator iter=m.begin();
    while(iter!=m.end())
    {
        cout<<iter->first;
        iter++;
    }
    cout<<m["!!!"];
    return 0;
}

针对m的过程

  1. 在m中查找hello的元素,但未找到
  2. 将hello作为key插入m中,类型为const string, 在例子中初始值为0
  3. 将键值对插入到m中
  4. 读取插入的元素, 对其赋值为1
  5. 同理,m[“world”]与m[“hello”]的过程类似
  6. 最后的m[“!!!”]表示: 访问下标(key)未在m中的键值对,那么将会在m中添加当前键, 其值初始化为0(使用默认的构造函数进行初始化)

注:map采用下标的访问过程与vector截然不同, map中如上第6步操作, 而vector将会抛出异常

map中insert的使用
map中的insert用法与顺序容器一致, 不同在于插入的元素必须是pair类型的
map提供的insert

  • m.insert(e): e是与m类型一致的pair类型, 如果e.first不存在m中, 那么将插入e.first作为键, 其值为e.second, 返回void; 若e存在m中则返回一个pair类型对象(假设对象名是p), p.first的值是map型迭代器(迭代器指向的位置是e.first), p.second的值是一个bool类型对象(值为false), 表示是否插入该元素
  • m.insert(b,e): 插入迭代器b,e范围之间的元素(元素类型必须为m.value_type类型的键值对), 不能指明总共插入多少个元素
  • m.insert(iter,e): 以iter为起点位置,自动查找可适合的新元素储存位置, 返回一个迭代器指向当前插入的元素的位置

注:插入的元素对象既可以是pair,也可以是map< T1,T2 >::value_type(key,value); 谨记value_type是pair< const key, value >的同义词
例: 用于解释m.inset(e)的返回值操作

//统计文章中单词出现的个数
map<string,int>m;
pair<string,int>p_tran//将每次输入的world转化为pair类型
string world
while(cin>>world){
    pair<map<string,int>::iterator,bool>p_sum=m.insert( p_tran(world,1) );
    if(!p_sum->second)
        ++(p_sum->first->second);   //表示对m中元素的值进行自增,不加括号时,注意符号优先级
}
map<string,int>::iterator iter=m.bengin();
while(iter!=m.end()){
    cout<<iter->first<<" 单词数目: "<<iter->second;
    ++iter;
}

p_sum的设计方式请参考m.insert(e)的返回值确定;

map中元素查找

  • 直接类似数组的下标方式进行查找, 但是若元素未在容器中将出现插入操作,且关联值为0, 给程序造成一定的负担
  • m.count(key): 返回m中key出现的次数
  • m.find(key): key存在m中,返回指向key的迭代器, 不存在时返回超出末端的迭代器(所谓end())

map中元素的删除

  • m.erase(key): 在m中删除键为key的元素,返回size_type类型的值(表示删除的元素的个数)
  • m.erase(iter): 删除iter所指向的元素, iter!=end()且iter存在, 返回void
  • m.erase(b,e): 删除迭代器b,e范围(b,e必须为有效范围,指向m中的元素或最后一个元素的后一个位置)内的元素, 返回void

当进行map对象的遍历的时候,采用const_iterator型迭代器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值