STL map容器是否可以获取索引号

hackxq 2015-01-13 06:26:32
请问,如果我有一个map,需要将map里的数据同步到一个列表中.如果向map里插入数据后,我需要一个插入索引号(位置),向列表中进行相同的操作.

因为map无法获取索引号,请问有什么别的办法吗?

我想到的办法是遍历map,用遍历的循环值当索引号,如下:


class CWidget
typedef std::map<int, CWidget> MyMap
int key1, key2, key3;

MyMap::iterator It = m_map.begin();
int insertIndex = 0;
for (; It != m_map.end(); it++, insertIndex++)
{
if (!列表.find(it->first))
{
// 在列表中没有找到相应值,需要插入新值
列表.insert(insertIndex, it->second)
}
}


如以上情况,请问这样索引map中的值有问题吗?

另外,请问如果不遍历,在知道map中key的情况下,怎样获得索引号?

谢谢
...全文
956 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
gbb21 2015-01-15
  • 打赏
  • 举报
回复
你的需求就是有问题的。
野男孩 2015-01-15
  • 打赏
  • 举报
回复
非要加减迭代器计算位置,得用vector,但是用vector可就没有关联特性了
luciferisnotsatan 2015-01-14
  • 打赏
  • 举报
回复
引用 12 楼 hackxq 的回复:
[quote=引用 11 楼 iyomumx 的回复:] 你可能需要 std::priority_queue
其实就是用到的列表不支持排序,所以想用别的容器先排一下,然后再放入列表中[/quote] 看需求,如果list不是一直加加减减的话,要靠map来排序(保持有序),效率上不如往list里加完后,再排序
luciferisnotsatan 2015-01-14
  • 打赏
  • 举报
回复
引用 6 楼 hackxq 的回复:
[quote=引用 1 楼 mujiok2003 的回复:] 没有看明白你的需求。
简单的说,就是通过key,可以找出其在map中的迭代器,但我想获得的是这个key在map中对应的索引号,不知是否可以[/quote] key在map(红黑树)里面的位置是不固定的。所以你现在得到key1在x1的位置,等你往map里再添加一个元素,key1可能就不在x1位置了。
michael2988 2015-01-14
  • 打赏
  • 举报
回复
引用 10 楼 hackxq 的回复:
[quote=引用 9 楼 michael2988 的回复:] 如果你的列表在同步之前是没有数据的,这种方法应该能保证同步后仍然有序; 如果有数据的话,同步后,列表中的数据并不能保证有序。
列表就是开始没有数据,重点是,能不能这样代替在map中的的一个pair的“索引号”[/quote] map 本来就是通过 key 来索引的,按照你的想法,获取 insertIndex 后,倒是可能通过 insertIndex 获取相应的迭代器,进而获取对应的值, MyMap::iterator It = m_map.begin(); MyMap::iterator It2 = It + insertIndex;
hackxq 2015-01-14
  • 打赏
  • 举报
回复
引用 11 楼 iyomumx 的回复:
你可能需要 std::priority_queue
其实就是用到的列表不支持排序,所以想用别的容器先排一下,然后再放入列表中
iyomumx 2015-01-14
  • 打赏
  • 举报
回复
你可能需要 std::priority_queue
hackxq 2015-01-14
  • 打赏
  • 举报
回复
引用 9 楼 michael2988 的回复:
如果你的列表在同步之前是没有数据的,这种方法应该能保证同步后仍然有序; 如果有数据的话,同步后,列表中的数据并不能保证有序。
列表就是开始没有数据,重点是,能不能这样代替在map中的的一个pair的“索引号”
michael2988 2015-01-14
  • 打赏
  • 举报
回复
如果你的列表在同步之前是没有数据的,这种方法应该能保证同步后仍然有序; 如果有数据的话,同步后,列表中的数据并不能保证有序。
hackxq 2015-01-14
  • 打赏
  • 举报
回复
引用 3 楼 coding_hello 的回复:
map不支持这么玩。。。毕竟map设计出来是用来做映射查找的,不是按顺序随机访问的。 非要实现这功能,可以再建一个map,key就是map项的key,value就是当前对应的index,维护也麻烦,得按事务处理,不建议
看来没办法了?存入map里其实只是想获得有序数据,那只能换别的容器了?
hackxq 2015-01-14
  • 打赏
  • 举报
回复
引用 2 楼 fly_dragon_fly 的回复:
这就是排序的结果吧
没错!!就是想在列表里获得有序的数据,列表本身没办法排序,就先放到一个map里了
hackxq 2015-01-14
  • 打赏
  • 举报
回复
引用 1 楼 mujiok2003 的回复:
没有看明白你的需求。
简单的说,就是通过key,可以找出其在map中的迭代器,但我想获得的是这个key在map中对应的索引号,不知是否可以
michael2988 2015-01-14
  • 打赏
  • 举报
回复
std::map<>::insert 的第一个参数表示插入位置,应该是一个 iterator 才对
xiaohuh421 2015-01-14
  • 打赏
  • 举报
回复
map是一棵有序的数, 内部已经决定了位置, 你是不可能在任意位置插入的, map也没有提供insert方法. 要么自己写一个map, 要么就遵守规则.
luciferisnotsatan 2015-01-14
  • 打赏
  • 举报
回复
引用 17 楼 hackxq 的回复:
[quote=引用 14 楼 luciferisnotsatan 的回复:] [quote=引用 6 楼 hackxq 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] 没有看明白你的需求。
简单的说,就是通过key,可以找出其在map中的迭代器,但我想获得的是这个key在map中对应的索引号,不知是否可以[/quote] key在map(红黑树)里面的位置是不固定的。所以你现在得到key1在x1的位置,等你往map里再添加一个元素,key1可能就不在x1位置了。[/quote] 确实,我也考虑把map换成list。可是用list+排序后,我描述的情景里好像还是不可以被应用。 因为stl list也没有规定以下操作:

typedef std::list<Widget> MList;
MList::iterator it1, it2
it2 - it1;
既然it2 - it1操作没有被明确规定,我想就不能通过索引号(下标)来确定list中某个Widget的位置。 好像vector支持这个操作,但又会在随机位置删除元素,所以用vector不太合适。 我还是换换思路在那个不支持排序的列表上想办法吧[/quote] list又没有下标,就算是MFC的CList的GetAt函数,内部也是用遍历来完成移动到某个位置的。 如果你不用频繁在头部或中间插入元素的话,可以改用vector
hackxq 2015-01-14
  • 打赏
  • 举报
回复
引用 14 楼 luciferisnotsatan 的回复:
[quote=引用 6 楼 hackxq 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] 没有看明白你的需求。
简单的说,就是通过key,可以找出其在map中的迭代器,但我想获得的是这个key在map中对应的索引号,不知是否可以[/quote] key在map(红黑树)里面的位置是不固定的。所以你现在得到key1在x1的位置,等你往map里再添加一个元素,key1可能就不在x1位置了。[/quote] 确实,我也考虑把map换成list。可是用list+排序后,我描述的情景里好像还是不可以被应用。 因为stl list也没有规定以下操作:

typedef std::list<Widget> MList;
MList::iterator it1, it2
it2 - it1;
既然it2 - it1操作没有被明确规定,我想就不能通过索引号(下标)来确定list中某个Widget的位置。 好像vector支持这个操作,但又会在随机位置删除元素,所以用vector不太合适。 我还是换换思路在那个不支持排序的列表上想办法吧
超级能量泡泡 2015-01-14
  • 打赏
  • 举报
回复
hash_map + vector
野男孩 2015-01-13
  • 打赏
  • 举报
回复
map不支持这么玩。。。毕竟map设计出来是用来做映射查找的,不是按顺序随机访问的。 非要实现这功能,可以再建一个map,key就是map项的key,value就是当前对应的index,维护也麻烦,得按事务处理,不建议
fly_dragon_fly 2015-01-13
  • 打赏
  • 举报
回复
这就是排序的结果吧
mujiok2003 2015-01-13
  • 打赏
  • 举报
回复
没有看明白你的需求。
条款1:仔细选择你的容器 条款2:小心对“容器无关代码”的幻想 条款3:使容器里对象的拷贝操作轻量而正确 条款4:用empty来代替检查size()是否为0 条款5:尽量使用区间成员函数代替它们的单元素兄弟" 条款6:警惕C++最令人恼怒的解析 条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针 条款8:永不建立auto_ptr的容器 条款9:在删除选项中仔细选择 条款10:注意分配器的协定和约束 条款11:理解自定义分配器的正确用法 条款12:对STL容器线程安全性的期待现实一些 vector和string 条款13:尽量使用vector和string来代替动态分配的数组 条款14:使用reserve来避免不必要的重新分配 条款15:小心string实现的多样性 条款16:如何将vector和string的数据传给传统的API 条款17:使用“交换技巧”来修整过剩容量 条款18:避免使用vector 关联容器 条款19:了解相等和等价的区别 条款20:为指针的关联容器指定比较类型 条款21:永远让比较函数对相等的值返回false 条款22:避免原地修改set和multiset的键 条款23:考虑使用有序vector代替关联容器 条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择 条款25:熟悉非标准散列容器 迭代器 条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator 条款27:用distance和advance把const_iterator转化成iterator 条款28:了解如何通过reverse_iterator的base得到iterator 条款29:需要一个一个字符输入时考虑使用istreambuf_iterator 算法 条款30:确保目标区间足够大 条款31:了解你的排序选择 条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase 条款33:提防在指针的容器上使用类似remove的算法 条款34:注意哪个算法需要有序区间 条款35:通过mismatch或lexicographical比较实现简单的忽略大小写字符串比较 条款36:了解copy_if的正确实现 条款37:用accumulate或for_each来统计区间 仿函数、仿函数类、函数等 条款38:把仿函数类设计为用于值传递 条款39:用纯函数做判断式 条款40:使仿函数类可适配 条款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因 条款42:确定less表示operator< 使用STL编程 条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46:考虑使用函数对象代替函数作算法的参数 条款47:避免产生只写代码 条款48:总是#include适当的头文件 条款49:学习破解有关STL的编译器诊断信息 条款50:让你自己熟悉有关STL的网站 参考书目 附录A:区域设置和忽略大小写的字符串比较 附录B:在微软STL平台上的注意事项 词汇表 索引
不知道网上有没有Effective STL(中文),我找不到,我自己整理出了这个《Effective STL(中文)》共享给需要的人。

《Effective STL》目录:

前言
致谢
导读
容器
条款1:仔细选择你的容器
条款2:小心对“容器无关代码”的幻想
条款3:使容器里对象的拷贝操作轻量而正确
条款4:用empty来代替检查size()是否为0
条款5:尽量使用区间成员函数代替它们的单元素兄弟
条款6:警惕C++最令人恼怒的解析
条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针
条款8:永不建立auto_ptr的容器
条款9:在删除选项中仔细选择
条款10:注意分配器的协定和约束
条款11:理解自定义分配器的正确用法
条款12:对STL容器线程安全性的期待现实一些
vector和string
条款13:尽量使用vector和string来代替动态分配的数组
条款14:使用reserve来避免不必要的重新分配
条款15:小心string实现的多样性
条款16:如何将vector和string的数据传给传统的API
条款17:使用“交换技巧”来修整过剩容量
条款18:避免使用vector
关联容器
条款19:了解相等和等价的区别
条款20:为指针的关联容器指定比较类型
条款21:永远让比较函数对相等的值返回false
条款22:避免原地修改set和multiset的键
条款23:考虑使用有序vector代替关联容器
条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择
条款25:熟悉非标准散列容器
迭代器
条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator
条款27:用distance和advance把const_iterator转化成iterator
条款28:了解如何通过reverse_iterator的base得到iterator
条款29:需要一个一个字符输入时考虑使用istreambuf_iterator
算法
条款30:确保目标区间足够大
条款31:了解你的排序选择
条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase
条款33:提防在指针的容器上使用类似remove的算法
条款34:注意哪个算法需要有序区间
条款35:通过mismatch或lexicographical比较实现简单的忽略大小写字符串比较
条款36:了解copy_if的正确实现
条款37:用accumulate或for_each来统计区间
仿函数、仿函数类、函数等
条款38:把仿函数类设计为用于值传递
条款39:用纯函数做判断式
条款40:使仿函数类可适配
条款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因
条款42:确定less表示operator<.
使用STL编程
条款43:尽量用算法调用代替手写循环
条款44:尽量用成员函数代替同名的算法
条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别
条款46:考虑使用函数对象代替函数作算法的参数
条款47:避免产生只写代码
条款48:总是#include适当的头文件
条款49:学习破解有关STL的编译器诊断信息
条款50:让你自己熟悉有关STL的网站
参考书目
附录A:区域设置和忽略大小写的字符串比较
附录B:在微软STL平台上的注意事项
词汇表
索引
关于本电子书
内容简介回到顶部↑这本书不适合C++ 初学者,不适合 Genericity(泛型技术)初学者,或 STL 初学者。这本书也不适合带领你学习面向对象(Object Oriented)技术 — 是的,STL 与面向对象没有太多关连。本书前言清楚说明了书籍的定位和合适的读者,以及各类基础读物。如果你的Generic Programming/STL实力足以阅读本书所呈现的源码,那么,恭喜,你踏上了基度山岛,这儿有一座大宝库等着你。源码之前了无秘密,你将看到vector的实现、list的实现、heap的实现、deque的实现、RB-tree的实现、hash-table的实现、set/map 的实现;你将看到各种算法(排序、搜寻、排列组合、数据移动与复制…)的实现;你甚至将看到底层的memory pool 和高阶抽象的traits 机制的实现。那些数据结构、那些算法、那些重要观念、那些编程实务中最重要最根本的珍宝,那些蜇伏已久彷佛已经还给老师的记忆,将重新在你的脑中闪闪发光。 目录回到顶部↑庖丁解牛(侯捷自序) i 目录 v 前言 xvii 本书定位 xvii 合适的读者 xviii 最佳阅读方式 xviii 我所选择的剖析对象 xix 各章主题 xx 编译工具 xx 中英术语的运用风格 xxi 英文术语采用原则 xxii 版面字形风格 xxiii 源码形式与下载 xxiv 在线服务 xxvi 推荐读物 xxvi 第1章 STL 概论与版本简介001 1.1 STL 概论 001 1.1.1 STL的历史 003 1.1.2 STL与C++ 标准程序库 003 . 1.2 STL 六大组件 - 功能与运用 004 1.3 GNU源码开放精神 007 1.4 HP STL实现版本 009 1.5 P.J. Plauger STL实现版本 010 1.6 Rouge Wave STL实现版本 011 1.7 STLport 实现版本 012 1.8 SGI STL实现版本 总览 013 1.8.1 GNU C++ header 文件分布 014 1.8.2 SGI STL 文件分布与简介 016 STL 标准头文件(无扩展名) 017 C++ 标准规格定案前,HP规范的STL头文件(扩展名 .h) 017 SGI STL 内部文件(SGI STL真正实现于此) 018 1.8.3 SGI STL 的组态设定(configuration) 019 1.9可能令你困惑的C++ 语法 026 1.9.1 stl_config.h 中的各种组态 027 组态3:static template member 027 组态5:class template partial specialization 028 组态6:function template partial order 028 组态7:explicit function template arguments 029 组态8:member templates 029 组态10:default template argument depend on previous template parameters 030 组态11:non-type template parameters 031 组态:bound friend template function 032 组态:class template explicit specialization 034 1.9.2 临时对象的产生与运用 036 1.9.3 静态常数整数成员在class 内部直接初始化 037 in-class static const integral data member initialization 1.9.4 increment/decrement/dereference 运算子 037 1.9.5 "前闭后开"区间表示法 [ ) 039 1.9.6 function call运算子(operator()) 040 第2章 空间配置器(allocator) 043 2.1 空间配置器的标准接口 043 2.1.1 设计一个简单的空间配置器,JJ::allocator 044 2.2 具备次配置力(sub-allocation)的SGI 空间配置器 047 2.2.1 SGI 标准的空间配置器,std::allocator 047 2.2.2 SGI 特殊的空间配置器,std::alloc 049 2.2.3 构造和析构基本工具:construct() 和 destroy() 051 2.2.4 空间的配置与释

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧