推回地图容器
Posted
技术标签:
【中文标题】推回地图容器【英文标题】:push back for the map container 【发布时间】:2013-03-08 13:54:07 【问题描述】:我们得到了这张地图:
std::map <int, int> values;
这个函数会和 Vector 的 push_back 函数一样吗:
void PushBack(int value)
values[values.size()] = value;
由于 size 返回容器的大小,我认为它是正确的,根据以下场景它是: 索引 0 = 200 索引 1 = 150 你想推回 100,values.size() 会返回 2,对吧?那么,它会像正常的 push_back 一样进入索引 2,对吗?
【问题讨论】:
values[values.size()]
会给你一个运行时错误,因为你想在容器的末尾添加一个过去的项目。
如果您想要顺序存储,请使用向量。使用地图作为矢量没有任何优势。
@bash.d 不,values
是一张地图。如果键不存在,它的 operator[]
会创建一个条目。
@bash.d - 不在这里;当未找到传递给运算符的键时,std::map
的索引运算符会创建一个新条目。
好的,各位,多谢指教!
【参考方案1】:
地图的全部意义在于根据唯一代表该数据的键来查找和存储数据。
如果你这样做,那么使用地图就没有意义了;您应该选择另一种更能满足应用程序设计需求的数据结构。
【讨论】:
+1、std::vector
和 std::map
存在于不同的目的,在有意义的地方使用它们。
这并不完全正确,通常需要扩展 OP,以便在其他速度较慢的容器上实现缺少的方法(显然,速度慢取决于特定的应用程序及其使用,但是一个典型的场景/example 使用std::map<int,T>
而不是std::vector<T>
和std::list<T>
当你必须快速访问和擦除元素)。【参考方案2】:
地图和矢量非常不同。
您提出的实际问题的简短版本:
如果您在自定义地图上所做的只是基于键查找已经存在的键(运算符 [])和您的 push_back,它可能会像只使用矢量运算符 [] 的矢量的低效替代品和 push_back,是的。
提供一些背景说明您所做的事情可能并不是您真正想要的:
地图没有索引,它有一个键。地图通常实现为红黑树。这样的数据结构允许基于键的有效查找。您通常关心特定元素的键,键本身携带重要信息。键通常不连续,映射不会为映射中未使用的键分配空间。
向量是一个连续的内存块。这允许有效的索引访问。索引与键不同:您通常不关心特定元素获得哪个索引,您获得的索引取决于插入顺序(它们的键与映射中的插入顺序无关),向量中的索引始终是整数值,并且不能有不连续的索引。
如果您在地图中所做的只是您自己的自定义 push_back,那么在某些情况下它可能看起来像一个向量,而在其他情况下它可能不会以某种方式运行(例如迭代器失效)。
由于您实际上并不关心示例中添加的元素的键,因此选择地图是没有意义的。向量中的索引查找会更快,并且内存开销会更小(尽管如果分配了很多对象,最终可能会出现内存碎片问题,但这是一个单独的主题)。
最后,如果您不知道要使用哪个容器类,则可以从 vector 和 list 开始。了解这两者之间的区别,以及何时应该使用它们中的任何一个,然后转向更高级、更专业的容器,例如 map、set、它们的“multi”变体和“unordered”变体。
【讨论】:
【参考方案3】:除非您仅以非常特殊的方式使用地图,否则它是不正确的。考虑这种情况:
std::map<int, int> values;
values[1] = 42;
PushBack(7);
values
现在只包含一个元素7
,索引为1
。
当然,问题是,如果您需要“后退”,为什么首先要使用地图。
【讨论】:
【参考方案4】:如果您想要push_back
,请考虑使用std::vector
。 map 是一个关联数组,用于通过指定类型的键进行快速查找。它们的设计目的不是像 vector 那样 push_back。
【讨论】:
【参考方案5】:很难说你想要达到什么,以及为什么你尝试使用地图而不是矢量,但更好的方法可能是:
void PushBack(int value)
int idx = 0;
if( values.size() ) idx = values.rbegin()->first + 1;
values[idx] = value;
【讨论】:
以上是关于推回地图容器的主要内容,如果未能解决你的问题,请参考以下文章