我想比较用整数填充的向量元素来查看是否 对于具有相同值的元素(并计算它们)。
例如,如果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
元素。 (由于b
和b
的元素按升序存储,一旦我要比较的a
元素大于N*M
的元素,我改变了向量on&gt; = not ==)
我认为这对于调用自身的函数应该很容易。 但我无法绕过它。
我希望有人能够理解我正在尝试做什么,但我现在无法更好地解释它。从理论上讲,我认为按升序排列的矢量应该更快,因为你只需进行N次比较(N是较大矢量的大小)而不是<form name='DataForm' action='nextpage.php' method='post'
onsubmit='return Ask()'>
</form>
。
答案 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的答案完全相同,只是从“不同的有利位置”表达。
但是,如果这两个向量的长度明显不同(比如,a
比b
短得多)那么接受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中进行一次检查。