算法取交集
先排序两个先行表,然后去除重复项。
从一个表(a)第一项开始,为关键字扫描另一个表(b),找一个与其相等的,如果找到,那么在b表之前的项也不会是a表中的项了,然后从a表下一项作关键字,从b表被匹配的元素的下一项开始继续搜索,如果没有找到与a中第一项相等的,到遇到比该项大的项时,便从a中下一项开始,重复以上步骤。
排序就不说了,好多种,冒泡,快排,插入,二分插入都行。去除重复项,可以用以下算法
void StripRepeatElement(int Array[],int Arraylen)
{
int Count = 0;//重复计数器
int i;
for(i = 0;i < ArrayLen;i++)
{
if(Array[i] == Array[i + 1])
{
Count++;
}
else
{
Array[i - Count] = Array[i];
}
}
}
复杂度为O(n)
以下为求交集的算法,假设两个表都已经排过序和剔出重复项了
void GetIntersection(int A[],int Alen,int B[],int Blen)
{
int i = 0,j = 0;
while(i < Alen)
{
while(j < Blen)
{
if(A[i] == B[j])
{
//交集
printf(" %d ",A[i]);
j++;
break;
}
else if(A[i] < B[j])
{
//从A的下一项开始匹配
break;
}
else
{
//比较B的下一项
j++;
}
}
i++;
}
}
复杂度也为O(n)
2. 有什么好的算法求两个数组的交集
首先对较短的一个数组(设长度为a)建立平衡二叉搜索树(需要alog2(a)的时间)。
然后对另一个数组(设长度为b)的每一个元素,在a的搜索树中查找(需要blog2(a)的时间)。
所以总共需要alog2(a)+blog2(a)的时间。
而2楼的算法需要ab的时间。
当b>a>4时,
a>2log2(a)
log2(a)<a-log2(a)
log2(a)/(a-log2(a))<1
alog2(a)/(a-log2(a))<a
又b>a
alog2(a)/(a-log2(a))<b
alog2(a)<ab-blog2(a)
alog2(a)+blog2(a)<ab
所以b>a>4时我的算法比2楼快。
当然,还有常数项的问题,上面的“快”只是渐进意义上的快。
3. c语言求两个数组的并交集
只简单地分析了一下交集的情况,求并集类似。网络知道这个代码支持不怎么好,复制粘贴到 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 } ");
// 第一种方法
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 ", (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 ", (end - start) * 1000 / CLOCKS_PER_SEC);
// 接下来用两个比较大的数组,测试一下两种方法的效率
printf(" 下面是测试,求一个包含 100000 个元素和一个包含 199999 个元素的数组的交集: ");
#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 ", (end - start) * 1000 / CLOCKS_PER_SEC);
start = clock();
result_array_len = getIntersection(testArray1, len1, testArray2, len2, testArray);
end = clock();
printf("第一种方法用时:%d ms ", (end - start) * 1000 / CLOCKS_PER_SEC);
start = clock();
result_array_len = getIntersection_optimized(testArray1, len1, testArray2, len2, testArray);
end = clock();
printf("第二种方法用时:%d ms ", (end - start) * 1000 / CLOCKS_PER_SEC);
return 0;
}
注释应该说明得比较清楚了,这里就不赘言了。
下面分别是在 Windows 上 msvc 和 mingw 编译并运行的结果:
mingw
4. 求两个集合的交集,用c++语言写
#include<stdio.h>
double P[n1],Q[n2]; //R=P∩Q
double R[];
double TEMP;
for(i=0;i<n1;i++)
{for(j=0;j<n2;j++)
if(P[i]==Q[j])
{
TEMP=P[i];
R[m]=TEMP;
m++;
}
}
5. 求两个集合交集的算法
我这里有一个很强的,是以前的作业,功能有很多!
有问题来找小斌
QQ:504449327
#define
TRUE
1
#define
FALSE
0
#define
OK
1
#define
ERROR
0
#define
INFEASIBLE
-1
#define
OVERFLOW
-2
typedef
int
Status;
typedef
char
ElemType;
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<conio.h>
typedef
struct
NodeType
{
ElemType
data;
struct
NodeType
*next;
}
NodeType,*LinkType;
typedef
struct
{
LinkType
head,tail;
int
size;
}OrderedList;
ElemType
a[100]="magazine";
ElemType
b[100]="paper";
OrderedList
L1,L2,L3;
Status
MakeNode(LinkType
&p,ElemType
e)/*函数功能,创建一个结点,用p指向它,并把e的值赋给date*/
{
p=(LinkType)malloc(sizeof(NodeType));
if(!p)
return
FALSE;
p->data=e;
p->next=NULL;
return
TRUE;
}
Status
InitList(OrderedList
&L)
/*函数功能,建立空栈*/
{
if(MakeNode(L.head,'
'))
{
L.tail=L.head;
L.size=0;
return
TRUE;
}
else
{
L.head=NULL;
return
FALSE;
}
}
Status
LocateElem(OrderedList
L,
ElemType
e,
LinkType
&p)
{
NodeType
*pre;
if(L.head)
/*栈建立成功*/
{
pre=L.head;
p=pre->next;
while(p
&&
p->data<e)
/*第二个结点中的data比e小,就让p和pre指向下一个结点*/
{
pre=p;
p=p->next;
}
if(p
&&
p->data==e)/*找到和e相等的date,p指向这个结点*/
{
return
TRUE;
}
else
/*如果找不到,p指向刚好比e小的结点*/
{
p=pre;
return
FALSE;
}
}
else
return
FALSE;
}
void
InsertAfter(OrderedList
L,
LinkType
q,
LinkType
s)
/*在结点q之后插入s结点*/
{
if(L.head
&&
q
&&
s)
{
s->next=q->next;
q->next=s;
if(L.tail==q)
L.tail=s;
L.size++;
}
}
void
CreateSet(OrderedList
&T,
char
*s)/*将s中的元素按从小到大的顺序插入到T控制的链表中*/
{
unsigned
i;
LinkType
p
,q;
if(InitList(T))
/*建立一个空栈*/
{
for(i=0;i<=strlen(s);i++)
{
if(s[i]>='a'
&&
s[i]<='z'
&&
!LocateElem(T,s[i],p))
{
if(MakeNode(q,s[i]))
{
InsertAfter(T,p,q);
}
}
}
}
}
Status
Print(LinkType
p)/*输出一个链表*/
{
if(p)
{
printf("%c",p->data);
return
TRUE;
}
else
return
FALSE;
}
void
ListTraverse(LinkType
p,
Status
(*visit)(
LinkType
))
{
printf("%c",'\t');
while(p)
{
visit(p);
//这句看不懂
p=p->next;
}
printf("%c",'\n');
}
void
Append(OrderedList
&L,LinkType
s)
{
if(L.head
&&
s)
{
if(L.tail!=L.head)
L.tail->next=s;
else
L.head->next=s;
L.tail=s;
L.size++;
}
}
void
Union(OrderedList
&T,OrderedList
S1,OrderedList
S2)
{
LinkType
p1,p2,p;
if(InitList(T))
{
p1=S1.head->next;
p2=S2.head->next;
while(
p1
&&
p2)
{
if(p1->data<=p2->data)
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p1->data;
p->next=NULL;
Append(T,p);
if(p1->data==p2->data)
p2=p2->next;
p1=p1->next;
}
else
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p2->data;
p->next=NULL;
Append(T,p);
p2=p2->next;
}
}
while(p1)
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p1->data;
p->next=NULL;
Append(T,p);
p1=p1->next;
}
while(p2)
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p2->data;
p->next=NULL;
Append(T,p);
p2=p2->next;
}
}
}
void
Intersection(OrderedList
&T,OrderedList
S1,OrderedList
S2)
{
LinkType
p1,p2,p;
if(!InitList(T))
T.head=NULL;
else
{
p1=S1.head->next;
p2=S2.head->next;
while(
p1
&&
p2)
{
if(p1->data<p2->data)
p1=p1->next;
else
if(p1->data>p2->data)
p2=p2->next;
else
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p1->data;
p->next=NULL;
Append(T,p);
p2=p2->next;
p1=p1->next;
}
}
}
}
void
Difference(OrderedList
&T,OrderedList
S1,OrderedList
S2)
{
LinkType
p1,p2,p;
if(!InitList(T))
T.head=NULL;
else
{
p1=S1.head->next;
p2=S2.head->next;
while(
p1
&&
p2)
{
if(p1->data<p2->data)
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p1->data;
p->next=NULL;
Append(T,p);
p1=p1->next;
}
else
if(p1->data>p2->data)
p2=p2->next;
else
{
p1=p1->next;
p2=p2->next;
}
}
while(p1)
{
p=(LinkType)malloc(sizeof(NodeType));
p->data=p1->data;
p->next=NULL;
Append(T,p);
p1=p1->next;
}
}
}
void
ReadCommand(char
&cmd)
{
printf("\n
------------------------------------------------------------------------\n");
printf("\n\t\t\t\t操
作
提
示");
printf("\n
------------------------------------------------------------------------\n");
printf("\tMakeSet1------1\t\t\t\tMakeSet2--------2\n\tUnion---------u\t\t\t\tIntersection----i\n\tDifference----d\t\t\t\tQuit------------q\n\tDisplay-------y");
do{
printf("\n\n\t请选择操作:");
cmd=getch();
printf("\n--------------------------------------------------------------------------\n");
}while(cmd!='1'
&&
cmd!='2'
&&
cmd!='u'
&&
cmd!='i'
&&
cmd!='d'
&&
cmd!='q'
&&
cmd!='y');
}
void
Interpret(char
&cmd)
{
system("cls");
switch(cmd)
{
case
'1':
printf("\n\t请输入字符串:");
gets(a);
printf("\t原始字符串:");
printf("\t%s\n",a);
CreateSet(L1,
a);
printf("\t构建的集合:");
ListTraverse(L1.head->next,Print);
break;
case
'2':
printf("\n\t请输入字符串:");
gets(b);
printf("\t原始字符串:");
printf("\t%s\n",b);
CreateSet(L2,
b);
printf("\t构建的集合:");
ListTraverse(L2.head->next,Print);
break;
case
'u':
CreateSet(L1,
a);
CreateSet(L2,
b);
Union(L3,L1,L2);
printf("\n\t集合1:");
ListTraverse(L1.head->next,Print);
printf("\t集合2:");
ListTraverse(L2.head->next,Print);
printf("\t并集:");
ListTraverse(L3.head->next,Print);
break;
case
'i':
CreateSet(L1,
a);
CreateSet(L2,
b);
Intersection(L3,L1,L2);
printf("\n\t集合1:");
ListTraverse(L1.head->next,Print);
printf("\t集合2:");
ListTraverse(L2.head->next,Print);
printf("\t交集:");
ListTraverse(L3.head->next,Print);
break;
case
'd':
CreateSet(L1,
a);
CreateSet(L2,
b);
Difference(L3,L1,L2);
printf("\n\t集合1:");
ListTraverse(L1.head->next,Print);
printf("\t集合2:");
ListTraverse(L2.head->next,Print);
printf("\t差集:");
ListTraverse(L3.head->next,Print);
break;
case
'y':
printf("\n\t原始字符串:\n");
printf("\t\t%s\n\t\t%s\n",a,b);
CreateSet(L1,
a);
CreateSet(L2,
b);
printf("\t由字符串构建的集合:\n");
printf("\t");
ListTraverse(L1.head->next,Print);
printf("\t");
ListTraverse(L2.head->next,Print);
Union(L3,L1,L2);
printf("\t并集:");
ListTraverse(L3.head->next,Print);
Intersection(L3,L1,L2);
printf("\t交集:");
ListTraverse(L3.head->next,Print);
Difference(L3,L1,L2);
printf("\t差集:");
ListTraverse(L3.head->next,Print);
break;
}
}
void
main()
{
char
cmd;
do
{
ReadCommand(cmd);
Interpret(cmd);
}while(cmd!='q');
}
6. python 多个字符串交集算法
如果原数据是唯一的,就把每一个元素,添加到一个字典中
最终获得类似{"A1":5,"A3":2,"D1":5,"D3":10}的字典,也就是记录每一个元素出现的次数,如果是10个元组的交集,那么次数=10。
7. 如何写一个c语言程序求两个集合的交集
定义两个数组存放这两个集合,再定义一个数组存放它们的集合,用类似冒泡排序的算法,遍历数组1中的第一个元素和数组2中每一个元素,若有相同的,则把这个元素放入第三个数组,继续遍历,知道数组1遍历完所有元素,那数组3中的元素,即为两个数组(集合)的交集。