我正在尝试遍历向量(k),并检查它是否包含值(键),如果有,我想添加在不同向量(val)的相同索引处找到的值然后将那里找到的任何值添加到第三个向量(temp)。
for(int i = 0; i < k.size(); ++i)
{
if(k.at(i) == key)
{
temp.push_back(val.at(i));
}
}
我最近学到了很多,但我在C ++中仍然没有超级高级,这段代码确实适用于我的目的,但速度非常慢。它可以处理大小为10或100的小向量,但对于大小为1000,10000甚至1000000的大小需要花费太长时间。
我的问题是,有更快更有效的方法吗?
我试过这个:
std::vector<int>::iterator it = k.begin();
while ((iter = std::find(it, k.end(), key)) != k.end())
{
int index = std::distance(k.begin(), it);
temp.push_back(val.at(index));
}
我认为使用矢量迭代器可能会加快速度,但由于bad_alloc错误我无法确定如何修复,因此我无法使代码生效。
有谁知道我能做些什么才能让这段代码更多更快?
答案 0 :(得分:6)
以下是您可以做的一些事情:
预先分配temp
的数据,以便push_back
不会导致重复分配:
temp.reserve(k.size());
如果k
已排序,您可以利用这一事实来加快速度:
auto lowerIt = std::lower_bound(k.begin(), k.end(), key);
auto upperIt = std::upper_bound(k.begin(), k.end(), key);
for (auto it = lowerIt; it != upperIt; ++it)
temp.push_back(val[it - k.begin()]);
at
进行边界检查,因此它比[]
慢一点。你显然必须保证你永远不会访问越界索引。答案 1 :(得分:2)
除了Rakete的建议:
如果您的键向量已排序 - 使用std::binary_search
而不是std::find
,然后迭代直到向量的下一个值/结尾。
如果您可以随意更改数据结构,请将数据保存在std::unordered_multimap
中,然后使用equal_range
访问包含所需密钥的元素。