我有两个整数数组
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;
}
答案 0 :(得分:5)
只需使用hash table:
#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;
}
}
预计运行时 O(sizeA + sizeB)。
答案 1 :(得分:1)
在数据结构中保存数组A
数组是数据结构;没有必要将A保存为一个。
我想比较所有元素直到大小A或B然后我会得到交集
这是非常模糊的,但不太可能产生交集;请注意,您必须检查A和B中的每个元素,但“直到大小A或B”将忽略元素。
我应该遵循什么方法来获取未知大小数组的大小并将其存储在容器中?
不可能在C中处理未知大小的数组,除非它们有一些允许计算元素数量的数组末尾标记(如NUL终止字符数组的情况,通常在C为“字符串”)。但是,数组的大小是已知的,因为它们的编译时大小是已知的。您可以使用宏计算此类数组中的元素数量:
#define ARRAY_ELEMENT_COUNT(a) (sizeof(a)/sizeof *(a))
...
int * ptr = new sizeof(A);
[您的问题最初标记为[C],我的评论在下面引用]
这是无效的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 ++中,您将使用new
和delete
]
但是,除非您需要对它们进行排序(参见下文),否则无需复制数组以查找交集,但还需要保留原始顺序。
有几种方法可以找到两个数组的交集。如果值落在0-63的范围内,则可以使用两个unsigned long
并设置与每个数组中的值对应的位,然后使用&
(按位“和”)查找路口。如果值不在该范围内,则最大值和最小值之间的差值<1。 64,您可以使用相同的方法,但从每个值中减去最小值以获得位数。如果范围不是那么小但是不同值的数量是&lt; = 64,则可以维护一个查找表(数组,二叉树,哈希表等),将值映射到位数和64元素数组将位数映射回值。
如果您的数组可能包含超过64个不同的值,则有两种有效的方法:
1)对每个数组进行排序,然后逐个元素地比较它们以找到常用值 - 这个算法类似于合并排序。
2)将一个数组的元素插入快速查找表(哈希表,平衡二叉树等),然后在查找表中查找另一个数组的每个元素。
答案 2 :(得分:0)
对两个数组进行排序(例如,qsort()
),然后一次遍历两个数组中的一个元素。
如果匹配,请将其添加到第三个数组,该数组的大小应与两个输入数组中较大的一个匹配(结果数组不能大于两个数组中的最大数组)。使用否定或其他&#34;虚拟&#34;作为终结者的价值。
当遍历输入数组时,第一个数组中的一个值大于另一个数组,移动第二个数组的索引,反之亦然。
当你完成两个阵列的步骤时,你的第三个阵列有你的答案,直到终结者值。
答案 3 :(得分:0)
您可以对两个数组进行排序
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)。
此算法所需的额外内存是最佳的(等于交叉点的大小)。