我必须存储映射到其他整数的整数值。一种方法是使用std :: map m。但是然后使用m [int]或m.find(int)检索值,将是logN(N是元素数)时间的顺序。在我的情况下,N非常大(最多2 ^ 30)。我认为使用std :: vector将更快访问,因为每个键现在映射到vector元素的索引,可以在O(1)时间访问。密钥以随机顺序遇到,它们可能不是连续的。例如,如果向量的大小为10,那么并非所有10个元素都有效,并且只能有6个有效元素,其余的我需要用-1填充。我写了一个小程序,我很惊讶地发现下面的输出:
int main () {
std::vector<int> v;
v.assign(6, -1);
v[3] = 10;
v[10] = 100;
cout << v.size() << v.capacity() << endl ;
cout << v[3] << v[10] << endl;
}
看到的输出是size = 6,capacity = 6,V [3] = 10,v [10] = 100.我不明白大小和容量是多少,但v [10]有一个有效值或我没遇到过seg。故障。有人可以解释一下吗?我的理解是push_back函数在vector.size&gt;时动态调整向量的大小。 vector.capacity,operator []也这样做吗?为了安全起见,我将上面的代码重写为:
int main () {
std::vector<int> v;
v.assign(6, -1);
int key = getKey();
if (key < v.size())
v[key] = <correct value>;
else {
v.resize(key, -1); // I want to assign -1 to invalid elements
v[key-1] = <correct value>;
}
}
它似乎工作正常,但将key与v.capacity()进行比较然后调整向量大小会更好。
答案 0 :(得分:3)
我的理解是push_back函数动态调整向量的大小 当vector.size&gt; vector.capacity,operator []也这样做吗?
不,它没有。如果使用operator[]
访问向量的末尾,则代码的行为是未定义的。您必须明确调整向量的大小,以确保它足够大,可以通过operator[]
进行任何访问。
std::vector::at()
与operator[]
类似,但确实执行错误检查,因此可用于发现越界访问(但执行这些额外检查会产生性能成本)
如果您希望数据结构相对稀疏,则可能需要考虑std::unordered_map
作业。
在任何情况下,我希望您意识到2^30
整数将占用相当数量的RAM(如果int
为32位宽,则为4GB)。即使你的硬件/操作系统允许你有一个很大的阵列,你可能不得不预先分配它而不是通过重复重新分配来增加它。
答案 1 :(得分:1)
std::vector<int> v;
v.assign(6, -1);
v[3] = 10;
v[10] = 100; // Unlucky with this statement
矢量的大小只是 6 。访问索引来自 0到5 。您的第一个代码段有未定义的行为,您不幸在访问索引 10 时没有中断。如果存在与值的关键关联的概念,则std::map
或std::multimap
等关联容器将优于std::vector
之类的序列容器。