快速向量元素比较

时间:2016-02-13 15:03:06

标签: c++

我想比较用整数填充的向量元素来查看是否 对于具有相同值的元素(并计算它们)。

例如,如果a[i]==x,是否有b[j]==x

首先想到的实现是当然最简单的实现:

for (int i=0; i < a.size(); i++) {
  for (int j=0; j < b.size(); j++) {
    if (a[i]==b[j]) {counter++;}
  }

这是减慢较大载体的方法。 我想过一个交替算法,但我不熟练实现 它是对的,所以在这里,我已经得到了什么和我的问题:

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (b[j] >= a[i]) {
        counter++;
        for (int k = i + 1; k < n; k++) {
          if (a[k] >= b[j+1]) {
            counter++;
            for (int l = k + 1; l < m; l++) {
              if (b[l] >= a[k]) {
                counter++;
                ....
              }
            }
          }
        }
      }
    }
  }

流程是我开始将a的第一个元素与b的元素进行比较。当我有一个点击时,我跳转到向量b并将其下一个元素与a的元素a进行比较,后者是我之前比较的a元素。 (由于bb的元素按升序存储,一旦我要比较的a元素大于N*M的元素,我改变了向量on&gt; = not ==)

我认为这对于调用自身的函数应该很容易。 但我无法绕过它。

我希望有人能够理解我正在尝试做什么,但我现在无法更好地解释它。从理论上讲,我认为按升序排列的矢量应该更快,因为你只需进行N次比较(N是较大矢量的大小)而不是<form name='DataForm' action='nextpage.php' method='post' onsubmit='return Ask()'> </form>

3 个答案:

答案 0 :(得分:3)

由于您声明元素按顺序存储,您可以执行以下操作:

int i=0;
int j=0;

while(i< a.size() && j<b.size()){
  if(a[i]==b[j]){
    ++counter;
    ++i;
    ++j;
  }else if(a[i]<b[j]){
    ++i;
  }else{
    ++j;
  }
}

答案 1 :(得分:3)

这是合并两个排序向量的经典问题的变体。

如果矢量已排序,您需要做的就是对矢量a中矢量b的连续元素执行增量线性搜索。 b中的每次搜索都从上一次搜索停止的位置开始。这种方法将进行O(a.size() + b.size())比较。

int count = 0;

int j = 0;
for (int i = 0; i < a.size(); ++i)
  for (; j < b.size() && b[j] <= a[i]; ++j)
    if (b[j] == a[i])
      ++count;

如果仔细观察,你会发现这与@Anedar的答案完全相同,只是从“不同的有利位置”表达。

但是,如果这两个向量的长度明显不同(比如,ab短得多)那么接受a的连续元素并执行<在b中搜索em> binary 。同样,b中的每次搜索都会从先前找到的b元素“向右”工作。这种方法将进行O(a.size() * log b.size())比较。

如果a.size() ~ b.size()O(a.size() + b.size())优于O(a.size() * log b.size())。但如果是a.size() << b.size(),那就是另一种方式。

答案 2 :(得分:0)

如果不需要使用向量,可以使用std :: multiset作为两个集合中值的容器。

此std :: multiset容器允许插入重复值,同时对值进行排序。您可以使用std :: multiset :: count。

获取元素的数量

将以O(logN)复杂度执行一次检查,以检查来自B的所有值是否包含在A中,并且在最坏的情况下复杂度的计数是否为M(logN)。使用std :: map可以实现相同,但是set比map更少占用内存,并且使用起来更简单。

如果某个值在集合B中不止一次,则只能在集合A中进行一次检查。