搜索值并在向量中返回索引的最有效方法是?

时间:2016-10-17 05:26:57

标签: c++ vector indexing

我正在尝试遍历向量(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错误我无法确定如何修复,因此我无法使代码生效。

有谁知道我能做些什么才能让这段代码更多更快?

2 个答案:

答案 0 :(得分:6)

以下是您可以做的一些事情:

  1. 预先分配temp的数据,以便push_back不会导致重复分配:

    temp.reserve(k.size());
    
  2. 如果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()]);
    
  3. at进行边界检查,因此它比[]慢一点。你显然必须保证你永远不会访问越界索引。

答案 1 :(得分:2)

除了Rakete的建议:

如果您的键向量已排序 - 使用std::binary_search而不是std::find,然后迭代直到向量的下一个值/结尾。

如果您可以随意更改数据结构,请将数据保存在std::unordered_multimap中,然后使用equal_range访问包含所需密钥的元素。