迭代C ++向量的最快方法

时间:2017-05-15 20:15:57

标签: c++ vector iteration time-limiting

我正在寻找有关矢量迭代的一些提示。 我正在尝试实现一个挑战,你必须实现一个函数(SumOfTwo),它接受两个向量和一个和作为参数,并且必须检查两个向量中是否有任何数字对,如果添加可以给出总和这是作为参数传递的。

我的功能正常,但它没有涵盖500毫秒的时间限制。 我觉得有一个更好的方法来迭代两个向量而不是两个for循环,但我觉得非常困难......

bool sumOfTwo(std::vector<int> a, std::vector<int> b, int v) {
    if((a.empty()) || b.empty()){
        return false;
    }
    for (std::vector<int>::iterator it1 = a.begin(); it1<=a.end(); ++it1)     {
            for (std::vector<int>::iterator it2 = b.begin(); it2<=b.end(); ++it2) {
                if ((*it1 + *it2) == v){
                    return true;
                }
            }
    }
    return false;
}

3 个答案:

答案 0 :(得分:5)

关于样式提示,请将代码更改为以下内容(为了提高效率和整洁度)

bool sumOfTwo(const std::vector<int>& a, const std::vector<int>& b, int v) {
    for (auto i1 : a)     {
            for (auto i2 : b) {
                if ((i1 + i2) == v){
                    return true;
                }
            }
    }
    return false;
}

考虑使用std::unordered_set并交叉引用它来查找是否可以获得最大效率。请记住,std::unordered_set中的查找是O(1)

答案 1 :(得分:3)

为什么算法慢?

目前,您正在迭代两个向量,但您正在进行嵌套迭代。让我们调用向量mn的长度(任意)。您当前的算法是O(n * m),对于大型矢量来说速度非常慢。

如果m = n = 1000,在最坏的情况下(没有两个元素总和为v),你正在进行数百万次操作 - 哇!

如何改善表现?

我可以想到一个巨大的加速:给定一个向量,a,一个向量b和一个所需的总和v,你可以从元素中创建一组数字 - va的明显区别,并检查b中的任何值是否在集合中。

伪代码是:

if a.empty or b.empty:
    return false

set = emptySet

for e in a:
    set.add(v - e)

for e in b:
    if e in set:
        return true

return false   

无序集合中的查找应为O(1),因此现在这是一个O(max(m,n))算法,其中m是a的长度,n是b的长度

如果m = n = 1000,在最坏的情况下,你现在正在进行数千次操作 - 好多了,对吧?

在C ++中实现它是留给读者的。 :)

提示:通过引用传递对于向量来说是一个好主意。

答案 2 :(得分:2)

谢谢大家的帮助! 我解决时间限制的方式是:

bool sumOfTwo(std::vector<int>& a, std::vector<int>& b, int v) {
   if((a.empty()) || b.empty()){
       return false;
   }
   std::unordered_set<int> s;
   for (const auto i : a) {
       s.insert(v-i);
   }
   for (const auto i : b) {
      auto search = s.find(i);
      if (search != s.end()) {
          return true;
      }
   }
   return false;
}