c语言求两个数组的并交集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言求两个数组的并交集相关的知识,希望对你有一定的参考价值。
参考技术A只简单地分析了一下交集的情况,求并集类似。百度知道这个代码支持不怎么好,复制粘贴到 vs 之类的代码编辑器里面缩进一下会比较好看。
见代码如下:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
// 使用整型数组为例,其它数组同理
// 交集
// 通过迭代遍历判断相同元素,时间复杂度较高,平方量级
// 传入原数组及其长度、结果数组
// 返回结果数组的长度
// (需要自行保证结果数组足够大)
size_t getIntersection(array1, array1_len, array2, array2_len, result_array)
int* array1, * array2, * result_array;
size_t array1_len, array2_len;
size_t result_p = 0;
for (size_t i = 0; i < array1_len; ++i)
for (size_t j = 0; j < array2_len; ++j)
if (array1[i] == array2[j])
result_array[result_p++] = array1[i];
break;
return result_p;
// 另一种思路是用快速排序等高效的排序算法先将数组排序,
// 然后再遍历一次数组,这时因为已经排好序了,所以最多只要
// 遍历 array1_len + array2_len 即可,此时时间复杂度较低,
// 因为快速排序等一般是 nlog(n),然后后面接一个一次量级的遍历,
// 总的来说是 nlog(n) + n,也就是 nlog(n),比 n^2 要快一些。
int intAscendingComparor(const void* left, const void* right)
return *(int*)left - *(int*)right;
// 交集
// 先排序后遍历判断相同元素,时间复杂度较低
// 传入原数组及其长度、结果数组
// 返回结果数组的长度
// (需要自行保证结果数组足够大)
size_t getIntersection_optimized(array1, array1_len, array2, array2_len, result_array)
int* array1, * array2, * result_array;
size_t array1_len, array2_len;
size_t result_p = 0;
size_t i = 0;
// 使用标准库的 qsort 比较方便
int* tmpArray = (int*)malloc(sizeof(int) * (array1_len + array2_len));
for (i = 0; i < array1_len; ++i) tmpArray[i] = array1[i];
for (i = 0; i < array2_len; ++i) tmpArray[array1_len + i] = array2[i];
qsort(tmpArray, array1_len + array2_len, sizeof(int), intAscendingComparor);
for (size_t i = 0; i < array1_len + array2_len - 1; ++i)
if (tmpArray[i] == tmpArray[i + 1])
result_array[result_p++] = tmpArray[i];
do
++i;
while (i < array1_len + array2_len - 1 && tmpArray[i] == tmpArray[i + 1]);
free(tmpArray); tmpArray = NULL;
return result_p;
// 自定义的一个简单的输出数组内容的函数
void printArray(int* array, size_t len)
for (size_t i = 0; i < len - 1; ++i)
printf("%d, ", array[i]);
printf("%d", array[len - 1]);
int main()
clock_t start, end;
int first_array[5] = 1, 2, 3, 4, 5 ;
int second_array[4] = 4, 5, 6, 7 ;
printf("数组1为: 1, 2, 3, 4, 5 ,数组2为: 4, 5, 6, 7 \\n");
// 第一种方法
int result_array[10];
start = clock();
size_t result_array_len = getIntersection(first_array, 5, second_array, 4, result_array);
end = clock();
printf("交集为: ");
printArray(result_array, result_array_len);
printf(" ,使用时间:%d ms\\n", (end - start) * 1000 / CLOCKS_PER_SEC);
// 第二种方法
start = clock();
result_array_len = getIntersection_optimized(first_array, 5, second_array, 4, result_array);
end = clock();
printf("使用优化算法求出的交集: ");
printArray(result_array, result_array_len);
printf(" ,使用时间:%d ms\\n", (end - start) * 1000 / CLOCKS_PER_SEC);
// 接下来用两个比较大的数组,测试一下两种方法的效率
printf("\\n下面是测试,求一个包含 100000 个元素和一个包含 199999 个元素的数组的交集: \\n");
#define len1 100000
#define len2 199999
int* testArray1 = (int*)malloc(sizeof(int) * len1);
int* testArray2 = (int*)malloc(sizeof(int) * len2);
int* testArray = (int*)malloc(sizeof(int) * len1);
start = clock();
for (size_t i = 0; i < len1; ++i) testArray1[i] = i;
for (size_t i = 0; i < len2; ++i) testArray2[i] = i + 12345;
end = clock();
printf("初始化数组用时:%d ms\\n", (end - start) * 1000 / CLOCKS_PER_SEC);
start = clock();
result_array_len = getIntersection(testArray1, len1, testArray2, len2, testArray);
end = clock();
printf("第一种方法用时:%d ms\\n", (end - start) * 1000 / CLOCKS_PER_SEC);
start = clock();
result_array_len = getIntersection_optimized(testArray1, len1, testArray2, len2, testArray);
end = clock();
printf("第二种方法用时:%d ms\\n", (end - start) * 1000 / CLOCKS_PER_SEC);
return 0;
注释应该说明得比较清楚了,这里就不赘言了。
下面分别是在 Windows 上 msvc 和 mingw 编译并运行的结果:
利用go语言实现求数组交集的算法
参考技术A题目: 给定两个数组,编写一个函数来计算它们的交集.(来自 leecode(349) )
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2] 示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4]
说明:
我的解法:
题目同上,只不过在输出的时候
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2,2] 示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4]
解法
如果给定的数组是排好序的,
arr1 = [1,2,3,4,4,13],arr2 = [1,2,3,9,10]
那这个返回值该如何获取得两个数组的交集呢?
解法
以上是关于c语言求两个数组的并交集的主要内容,如果未能解决你的问题,请参考以下文章