2d矢量和矢量地图有什么区别?
What's the difference between 2d vector and map of vector?
假设我已经声明
map< int , vector<int> > g1;
vector< vector<int> > g2;
这两者之间有什么相似之处和不同之处?
相似之处在于访问数据的方式,它可以是相同的语法:
std::cout << g1[3][2] << std::endl;
std::cout << g2[3][2] << std::endl;
主要区别在于:向量的映射不必包含所有索引。然后,例如,您可以使用键"17"、"1234"和13579
:访问地图中的3个矢量
g2[17].resize(10);
g2[1234].resize(5);
g2[13579].resize(100);
如果你想要一个矢量的语法相同,你需要在你的主矢量中至少有13579个矢量(包括13576个空矢量)。但这将占用内存中大量未使用的空间。
此外,在您的地图中,您还可以使用负键访问您的矢量(这在矢量的矢量中是不可能的):
g2[-10].resize(10);
在这种明显的高度差异之后,数据的存储就不同了。向量分配连续内存,而映射则存储为树。向量中访问的复杂性是O(1)
,而映射中访问的复杂度是O(log(n))
。我邀请您学习一些关于C++中容器的教程,以了解所有的差异以及使用它们的常用方法。
它们根本不同。虽然您可以同时执行g2[0]
和g1[0]
,但行为却大不相同。假设索引0处没有任何内容,则std::map
将默认构造一个新的value_type,在本例中为向量,并返回一个引用,而std::vector
具有未定义的行为,但通常是segfault或返回垃圾。
它们在内存布局方面也完全不同。当std::map
由红黑树支持时,std::vector
在内存中是连续的。因此,插入到映射中总是会导致内存中某个位置的动态分配,而向量会在超出其当前容量的情况下调整大小。然而,请注意,向量中的一个向量在内存中是不连续的。第一个矢量本身在内存中是连续的,它由在数据方面大致如下的矢量组成:
struct vector
{
T* data;
size_t capacity;
size_t size;
};
其中每个向量在CCD_ 10处拥有其动态存储器分配。
地图的优点是它不必人口稠密,也就是说,你可以在索引0和12902之间有一些东西,而不需要所有介于两者之间的东西,而且它是排序的。如果您不需要sorted属性并且可以使用c++11,请考虑std::unordered_map
。矢量总是密集分布的,即在大小为10000的情况下,存在元素0-9999。
通过示例,您可以理解其中的区别。假设vector<int>
存储人的唯一id,而map
存储各自的pincode作为密钥。
map< int , vector<int> > listOfPeopleAtRespectivePinCode;
vector< vector<int> > bunchOfGroupsOfPeople;
显然,map
能够关联密钥和值(这里是值的列表),而vector
可以有效地存储一堆数据。
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- Qt:remove() 和 rmdir() 有什么区别
- 这 4 个 lambda 表达式之间有什么区别?
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- typedef 枚举和枚举类有什么区别?
- &C::c 和 &(C::c) 有什么区别?
- ascii 和 unicode 在处理级别有什么区别吗?
- C 中的常量限定符和 C++ 中的常量限定符有什么区别?
- "ABC" 和 "ABC" ) 在C++中有什么区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- 两种访问I2C总线的方法有什么区别?
- 两种模板示例有什么区别?
- 这两种C++语法之间有什么区别?
- lua 5.0.2 模块和 5.3.5 有什么区别?
- C++中"typedef"、"using"、"namespace"和"using namespace"有什么区别?
- std::vector和llvm::SmallVector之间有什么区别?什么时候用哪一个