如何得到两个数组的交集

How to get intersection of two Arrays

本文关键字:数组 两个 何得      更新时间:2023-10-16

我有两个整数数组

    int A[] = {2, 4, 3, 5, 6, 7};
    int B[] = {9, 2, 7, 6};

我需要得到这两个数组的交点

。输出将为- 2,6,7

我想通过将数组A保存在数据结构中来解决这个问题,然后我想比较所有元素,直到大小A或B,然后我会得到交集。

现在我有一个问题,我需要首先将数组a的元素存储在容器中。

我应该这样做吗-

int size = sizeof(A)/sizeof(int);

要获取大小,但通过这样做,我将获得大小之后,我想访问所有的元素,并存储在一个容器

这里是我用来找到交集的代码->

#include"iostream"
using namespace std;

int A[] = {2, 4, 3, 5, 6, 7};
int B[] = {9, 2, 7, 6};
int main()
{
    int sizeA = sizeof(A)/sizeof(int);
    int sizeB = sizeof(B)/sizeof(int);
    int big =  (sizeA > sizeB) ? sizeA : sizeB;
    int small =  (sizeA > sizeB) ? sizeB : sizeA;
    for (int i = 0; i <big ;++i)
    {
        for (int j = 0; j <small ; ++j)
        {
            if(A[i] == B[j])
            {
                cout<<"Element is -->"<<A[i]<<endl;
            }
        }
    }
    return 0;
}

使用哈希表:

#include <unordered_set>  // needs C++11 or TR1 
// ...
unordered_set<int> setOfA(A, A + sizeA);

然后你可以检查B中的每个元素,它是否也在A中:

for (int i = 0; i < sizeB; ++i) {
    if (setOfA.find(B[i]) != setOfA.end()) {
        cout << B[i] << endl;
    }
}

预期运行时间 0 (sizeA + sizeB).

可以对两个数组进行排序

sort(A, A+sizeA);
sort(B, B+sizeB);

,并使用类似合并的算法找到它们的交集:

#include <vector>
...
std::vector<int> intersection;
int idA=0, idB=0;
while(idA < sizeA && idB < sizeB) {
    if (A[idA] < B[idB]) idA ++;
    else if (B[idB] < A[idA]) idB ++;
    else { // => A[idA] = B[idB], we have a common element
        intersection.push_back(A[idA]);
        idA ++;
        idB ++;
    }
}

这部分代码的时间复杂度是线性的。然而,由于数组的排序,整体复杂度变为O(n * log n),其中n = max(sizeA, sizeB)。

该算法所需的额外内存是最优的(等于交集的大小)。

在数据结构中保存数组A

数组数据结构;没有必要把A保存成一个。

我想比较所有元素直到大小A或B然后我将得到交集

这是非常模糊的,但不太可能产生交集;注意,你必须检查A和B中的每个元素,但是"till size A or B"会忽略元素。

我应该遵循什么方法来获取未知大小数组的大小并将其存储在容器中??

在C中不可能处理未知大小的数组,除非它们有一些允许计算元素数量的数组结束哨兵(就像以null结束的字符数组的情况一样,在C中通常称为"字符串")。但是,数组的大小是已知的,因为它们的编译时大小是已知的。可以使用宏

计算此类数组中的元素数量:
#define ARRAY_ELEMENT_COUNT(a) (sizeof(a)/sizeof *(a))

int *ptr = new sizeof(A);

[你的问题最初被标记为[C],我下面的评论是指那个]

这是无效的——new是一个c++关键字。

如果你想复制你的数组,你可以简单地使用,例如,

int Acopy[ARRAY_ELEMENT_COUNT(A)];
memcpy(Acopy, A, sizeof A);

或者,如果出于某种原因你想把副本放在堆上,

int* pa = malloc(sizeof A);
if (!pa) /* handle out-of-memory */
memcpy(pa, A, sizeof A);
/* After you're done using pa: */
free(pa);

[在c++中你会使用newdelete]

然而,没有必要为了找到交集而复制数组,除非你需要对它们排序(见下文),但又需要保持原始顺序。

有几种方法可以找到两个数组的交集。如果值在0-63的范围内,您可以使用两个unsigned long并设置每个数组中值对应的位,然后使用&(按位"answers")找到交集。如果值不在该范围内,但最大值和最小值之间的差值为<64,您可以使用相同的方法,但从每个值减去最小的值,以获得位数。如果范围不是那么小,但是不同值的数量是<= 64,则可以维护一个查找表(数组、二叉树、哈希表等),将值映射到位数,并维护一个64元素的数组,将位数映射回值。

如果你的数组包含超过64个不同的值,有两种有效的方法:

1)对每个数组进行排序,然后逐个元素比较它们以找到共同的值——该算法类似于归并排序。

2)将一个数组的元素插入快速查找表(哈希表、平衡二叉树等),然后在查找表中查找另一个数组的每个元素。

对两个数组(例如,qsort())进行排序,然后一次一个元素遍历两个数组。

如果有匹配项,将其添加到第三个数组中,该数组的大小与两个输入数组中较大的数组匹配(您的结果数组不能大于两个数组中最大的数组)。使用负值或其他"虚拟"值作为终止符。

遍历输入数组时,如果第一个数组中的一个值大于另一个值,则移动第二个数组的索引,反之亦然。

当您遍历两个数组时,第三个数组包含您的答案,直到结束符的值。