2017-10-10 254 views

回答

0

它们根本不同。虽然您可以同时执行g2[0]g1[0],但行为却大不相同。假设索引0处没有任何内容,那么std::map将默认构造一个新的value_type,在这种情况下是一个向量,并返回一个引用,而std::vector具有未定义的行为,但通常是段错误或返回垃圾。

它们在内存布局方面也完全不同。尽管std::map由红黑树支持,但std::vector在内存中是连续的。因此插入到映射中总是会导致内存中某处的动态分配,而向量将在其当前容量超过的情况下调整大小。但请注意,矢量矢量在内存中不是连续的。第一矢量,它本身是在存储器中连续由载体看起来大致是这样的在数据方面组成:

struct vector 
{ 
    T* data; 
    size_t capacity; 
    size_t size; 
}; 

这里每个矢量的拥有在data其动态存储器分配。

该地图的优点是不必密集填充,即可以在索引0和12902处没有所有东西之间的东西,再加上它被排序。如果你不需要排序的属性,并且可以使用C++ 11,请考虑std::unordered_map。矢量总是密集填充的,即在大小10000处,元素0-9999存在。

+0

请注意,RB树不是由标准指定的。它依赖于实现,即使在大多数情况下都是如此。 – Caduchon

+0

是真的,但是你知道一个不使用rb-tree的实现吗? IIRC标准通常只对某些操作要求某些渐近运行时间,但实际上,内存分配策略对大多数情况下的渐近运行时差异具有更大的影响。 – midor

+0

不,但是有这么多奇怪的编译器,如果其中一些实现其他算法(例如卡西欧或德州仪器,已经使用16位字节),我不会感到惊讶。 – Caduchon

1

的相似性是访问数据的方式,也可以是相同的语法:

std::cout << g1[3][2] << std::endl; 
std::cout << g2[3][2] << std::endl; 

的主要区别如下:矢量的地图没有包含所有的索引。然后,你可以有,如例子中,只有3地图中的向量与键“17”,“1234”和13579访问:

g2[17].resize(10); 
g2[1234].resize(5); 
g2[13579].resize(100); 

如果你想与向量的矢量相同的语法,你需要你的主向量中至少有13579个向量(包括13576个空向量)。但是这会在内存中使用很多未使用的空间。

另外,在映射图,也可以用负密钥访问自己的载体(这是不可能以向量为向量):

g2[-10].resize(10); 

这明显高差后,数据的存储是不同。矢量分配连续的内存,而地图以树的形式存储。向量中访问的复杂度为O(1),而在地图中则为O(log(n))。我邀请您学习一些关于C++中的容器的教程,以了解所有差异以及使用它们的常用方法。

0

用例子你可以理解它们之间的区别。假设vector<int>存储唯一的ID号码,并且map将各自的PIN码存储为密钥。

map< int , vector<int> > listOfPeopleAtRespectivePinCode; 
vector< vector<int> > bunchOfGroupsOfPeople; 

显然,map能够关联键和值(这里为值列表),而vector可以有效地存储一组数据。