简体   繁体   English

一般而言,在c ++中使用map或vector哪个更好?

[英]which is better in general, map or vector in c++?

As I know that accessing an element in vector takes constant time while in map takes logarithmic time. 据我所知,访问向量中的元素需要花费恒定的时间,而在映射中则需要对数时间。 However, storing a map takes less memory than storing a vector. 但是,存储地图比存储矢量占用更少的内存。

Therefore, I want to ask which one is better in general? 因此,我想问总体上哪个更好? I'm considering using one of those two in my program, which has about 1000 elements. 我正在考虑在我的程序中使用这两个之一,它大约有1000个元素。 I plan to use 3 dimensional vector, which would take 1000x1000x1000 elements. 我计划使用3维向量,它将采用1000x1000x1000个元素。

There is no correct answer to this question. 这个问题没有正确答案。 The correct question should be "which is better for the specific application --insert your project here--". 正确的问题应该是“哪个对特定应用程序更好-在此处插入您的项目-”。 To choose the correct container you need to explain how it will be used. 要选择正确的容器,您需要说明如何使用。

A map is an associative container -- it serves a completely different function from a vector. 映射是一个关联容器,它的功能与矢量完全不同。 Use a map if you want to associate keys with values. 如果要将键与值关联,请使用地图。 If your keys are just nonnegative consecutive integers, then a vector is superior in every way. 如果您的键只是非负连续整数,那么向量在每种方式上都是上乘的。

Vector and Map are two different containers used for different purposes. Vector和Map是用于不同目的的两个不同容器。 IF there was one better, the other would NOT exist ... 如果有一个更好的,另一个将不存在...

First of all, storing a map will almost definitely take more memory than a vector since a vector is simply a contiguous block and a map contains a tree structure. 首先,存储地图几乎肯定会比向量占用更多的内存,因为向量只是一个连续的块,并且地图包含树结构。

The answer to your question of which is better is that it depends on the problem you are trying to solve. 您的问题哪个更好的答案是,这取决于您要解决的问题。 It really comes down to how you want to be able to index your data. 这实际上取决于您希望如何为数据建立索引。 If your data can be indexed linearly by an integer, then vector will perform the best. 如果您的数据可以用整数线性索引,则矢量将是最佳的。

However, there are many cases where you'll want to access your data in some other way. 但是,在许多情况下,您将需要以其他方式访问数据。 For example, if you want to index your data using a string (like a dictionary lookup), then the map will perform better. 例如,如果您要使用字符串(例如字典查找)为数据建立索引,则地图的性能会更好。 To index data with a string using a vector, you would have to perform a linear search (O(n)) to find an element if you don't keep the vector sorted. 要使用向量对带有字符串的数据进行索引,如果不对向量进行排序,则必须执行线性搜索(O(n))来查找元素。 A map would only have to perform a binary search (O(log n)) which would be a LOT faster as n grows. 映射只需执行二进制搜索(O(log n)),随着n的增长,该搜索将更快。

There is no such thing as better in general. 总的来说,没有比这更好的了。 It all depends on the operations You are going to perform and on the frequency of those operations. 这完全取决于您要执行的操作以及这些操作的频率。

Vectors don't use more space than map, for the same number of elements. 对于相同数量的元素,向量不占用比地图更多的空间。 However such a thing, like a sparse matrix for example, sometimes may be implemented more efficiently using map. 但是,有时这种情况(例如,稀疏矩阵)可以使用map更有效地实现。

It is frankly rediculous to suggest that you creat 1,000,000,000, empty objects to store just 1000 useful ones. 坦率地说,建议您创建1,000,000,000个空对象以仅存储1000个有用对象。 If you think a vector will be faster, you are probably very wrong when you consider all the swapfile thrashing, dynamic memory allocation, and unnecessary object construction that will ensue! 如果您认为向量会更快,那么当您考虑所有交换文件崩溃,动态内存分配以及随之而来的不必要的对象构造时,您可能就错了!

The description of your application is probably too vague; 您的应用程序描述可能太含糊。 but if a value can be indexed by x,y,z; 但是如果值可以用x,y,z索引; then use an object containing x,y,z as the map key. 然后使用包含x,y,z的对象作为映射键。 It will not take long to locate just 1000 objects - that is a very small map. 仅定位1000个对象就不会花很长时间-这是一个很小的地图。

If you have sparse 3-dimension array, you can save a lot of memory using map with the key as combination of indexes. 如果您具有稀疏的3维数组,则可以使用map和键作为索引组合来节省大量内存。 For your case with indexes < 1000, key can be 32 bit unsigned integer: 对于索引小于1000的情况,键可以是32位无符号整数:

#include <stdint.h>
...
int index1 = 12, index2 = 34, index3 = 56;

// construct key:
uint32_t key = 
  ((index1&0x3FF) << 20) | 
  ((index2&0x3FF) << 10) | 
  (index3&0x3FF)
  );

// restore indexes:
index1 = (key >> 20) & 0x3FF;
index2 = (key >> 10) & 0x3FF;
index3 = (key) & 0x3FF;

Deque is a more appropriate replacement for a vector than a map. 与地图相比,双端队列更适合替代向量。 But it depends on your needs. 但这取决于您的需求。 A vector requires linear memory for all its data, but a deque does not. 向量需要线性存储所有数据,但双端队列则不需要。 And a deque is can be used as a drop in replacement for a vector in most cases. 在大多数情况下,双端队列可以用作替代向量的替代方法。

If you want a key-value component, use map. 如果需要键值组件,请使用map。 If you want a random-access-by-number solution, or an iteratively ordered solution, use vector. 如果要使用按数字随机访问的解决方案或迭代排序的解决方案,请使用向量。

Check your data structures/algorithm analysis text for more information. 检查数据结构/算法分析文本以获取更多信息。

I consider vector<> to be the best default choice of container (except for vector<bool> ). 我认为vector<>是容器的最佳默认选择( vector<bool>除外)。 If I have a reason to prefer another container, I use the other one; 如果我有理由偏爱另一个容器,请使用另一个容器。 if not, I use vector<> (or deque<bool> ). 如果没有,我使用vector<> (或deque<bool> )。 That's as close as I can get to "better in general". 这与“更好”有关。

There are reasons for all the STL containers, things they do better than any other one. 所有STL容器都有其原因,它们做得比其他任何容器都要好。 Without knowing what you're going to be using the data structure for, I can't be any more help. 不知道您将要使用数据结构做什么,我将无济于事。

However, the penalties for using the wrong structure go up with the size. 但是,使用错误结构的惩罚会随大小而增加。 If you have a few dozen elements, any class will do. 如果您有几十个元素,那么任何类都可以。 If you're talking about a billion elements, you really do want to get it right (and make sure your computer will handle it - you probably need a 64-bit app with a lot of RAM). 如果您正在谈论十亿个元素,那么您确实的确想弄清楚它(并确保您的计算机可以处理它-您可能需要一个具有大量RAM的64位应用程序)。

If your 3D matrix will be sparsely populated (ie mostly zeros), then you'll be interested in boost::ublas::sparse_matrix . 如果您的3D矩阵将被稀疏填充(即大部分为零),那么您将对boost::ublas::sparse_matrix If I recall correctly, by default, it uses std::map as the underlying container. 如果我没记错的话,默认情况下,它将使用std::map作为基础容器。 It provides operators for easy row/column indexing (as well as row/column/element iterators). 它为轻松的行/列索引(以及行/列/元素迭代器)提供了运算符。

EDIT: Nevermind, I thought boost::ublas had 3D matrices. 编辑:没关系,我以为boost :: ublas有3D矩阵。 It seems that it doesn't. 似乎没有。 It also seems that sparse_matrix has been replaced by new matrix types having sparse storage. 似乎sparse_matrix已被具有稀疏存储的新矩阵类型取代。 It's been a long time since I used that library. 自从我使用该库已有很长时间了。

You can still look at Boost.uBlas for inspiration in rolling your own sparse 3D matrix. 您仍然可以查看Boost.uBlas来获得滚动稀疏3D矩阵的灵感。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM