交集算法
⑴ 并集和交集的公式是什么
交集?并集?
你还记得高中数学的第一课吗?讲的是集合,具体定义去网络,里面有两个运算法则:交集和并集。也许你当时觉得很容易,那么今天还是回头想想它在讲什么。
一、两个集合
一切运算都是两个相对的集合间的关系法则,既然是高中数学,那么就略谈一下教育,其实很多人会说“你考好了说明学好了”,然而我想说的是考试和教学是两个集合。
我们看看中国过去的八股文,包括今天的高考,受到那么多诟病,但是为什么还是继续这么做?因为相关部门不知道,无作为?我觉得要是从另外一个角度看,考试作为一种人才选拔的工具,那选拔什么样的人呢?是见多识广、才华横溢的人;还是那些面对一个目标,能持之以恒地找方法达成,坐得住、能下功夫的人呢?
不好意思,答案很可能是后者。
现在很多创业公司都有这样的体会。招人的时候,他们往往不是倾向于招那些有经验的人,而倾向学习能力好、沟通能力强、对自己要求严、有自我驱动能力的人。因为创业公司本来做的就是全新的事情,经验这个东西是有益还是有害,说不清楚。但是面对任何新的情况,都能找到方法、诉诸行动、不丢目标的人,才是创业公司需要的。前一阵还有一位创业公司的创始人跟我说,他发现优秀的大学生,比行业里的老鸟好用。
这种优秀的人,不管面对什么样的题目,哪怕是八股文,也一样可以坐得住、下苦功,最后考出好成绩。这样的人走入仕途,面对自己不熟悉的任务,也一样会表现优秀。事实上,明清两代那么多能人都是靠八股文选拔出来的,比如我们熟悉的王阳明和曾国藩。
再回头来说我们的高考。
这几年,高考的发展趋势和八股文正好相反的,这也是很多人呼吁和推动的结果。各地高考越来越强调地方特色,越来越多地考核学生的所谓“综合素质”。这种发展方向看似正确,但是也有值得反思的地方。
首先,中国是一个大国,各地情况差异巨大,社会阶层也差异巨大。只有坚持全国的统一性,才能确保人才通过高考在全国范围内的流动和交流,维持整个国家的内在联系和国家认同。不夸张地说,如果高考的全国统一性消失了,中国各个地方的内在联系会被严重削弱。
我们不能把高考仅仅看作是教育的一个环节,高考是国家治理中的关键,事关国家的完整统一和治理水平。
其次,虽然不必恢复到八股文那样死板的形式,但高考仍然要尽量维持简单、明晰的考试内容和形式。一言以蔽之,永远要确保,学生只靠几本教科书、只比拼硬功夫、笨功夫就能取得好成绩。
和科举一样,高考不是教育工具,高考是人才选择的工具。它把各个社会阶层里奋发向上,能坐得住、下苦功夫的人挑选出来,保持这个社会的活力和公平。这才是高考在当前中国社会的真实作用。
然而,所谓教育则是一种能力的培养,一种思维模式的锻炼,比如我们讲集合,你不光会做题还要会应用,比如将学习数学思维和考试分开来,当然它们之间有交集,就是你既能坐下来刷题总结,又能进行发散和转化,你要既能学好集合又能考好集合这就是交集,而你只是明白自己要好好学习并且考试优异这就是并集。其实大多数人在看问题的时候喜欢用并集,这样比较省事,也符合原始的认知方式,然而今天这种方式与时代有所不匹配啦,这种人就是那些现在边缘只求安全感,却不愿多向集合内多走一步深入了解的人。我们在许多问题上可以有所区分,比如人工智能就是未来一切的引导?关系问题一定是其中一个人有问题或者两个人有问题?
二、人工智能就是人类的全部模拟?
这个的答案明显是否定的,人工智能是完全通过算法运行的,这些算法都来自于各个学科的模型计算,你去翻翻书,所以学科都有一个所谓的理想假设,这个假设通俗的讲就是,如果世界只有XX学科来指导运行的话。所以人工智能可以模拟任意学科,但是这是不同的集合,交集并不能完全模拟,对于这个问题,很多人认为只要融合了那么交集自然呈现啊,其实不然。举个例子,一些有经验的心理咨询师在处理感情纠葛问题时,会说他面对的是三个人,夫妻双方和他们的关系,而关系就是交集的结果,所以关系问题不一定是个人或者两个人的问题导致,也有可能是他们的交集,也就是产生的关系导致。再者人工智能更偏向科学,而科学思维和技术仅仅是社会中的小部分,还有大部分的人性,也就是社会科学,例如人工智能的围棋站,输的那一局就是输在人性上,所以任何复杂问题回答时,可以考虑下是否存在两个及以上集合,因为可能存在第三者。(上述问题因本文需求,不多做拓展)这样一个是非问题只有两个答案,却可能有三层认知。
三、认知三级跳
最近中子星的新闻应该都看过了,那么问个看问题,宇宙是有限的还是无限的?如果回答宇宙是有限大的,那说明这个人具备了一定的科学素养。如果他回答宇宙是无限大的,那就有两种可能。一种可能是这个人对现代科学一无所知;另一种可能,却是他对天体物理学的最新进展非常了解。
第一层,无限大,从小就知道宇宙浩瀚无边,没有天边,所以无限大。
第二层,有限大,知道宇宙大爆炸,就知道宇宙是个正在被吹大得气球,不管怎么变大,气球总还是有边界的,于是有限大。
第三层,无限大,根据2013最新发现,宇宙质能比例系数为1±0.004,以及宇宙背景辐射的数据,证明在欧几里得空间内,宇宙是一个平面,无限延伸。
那么又会出现一个特别有意思的情况,二八理论,如果去统计下会发现中间层的人会有80%,所以当你和很多别人的观点一样的时候就要警惕啦,你是不是中间层?你也许离出现集合只有一步,而你却沾沾自喜。
同样的事情我们看看对朋友圈的认识,最早用的时候,很多人不习惯的,认为不好所以希望不要有。当发现里面信息多样化,被设计吸引后,几乎大多数人都爱它。而像我自从写出那篇朋友圈是黑暗森林后,至今朋友圈没看过,而我并没有过不下去,或者对我的生活学习工作没有太大影响,那我还去看了干嘛,花去巨大的时间成本,却基本没有收益啊。
⑵ python 多个字符串交集算法
如果原数据是唯一的,就把每一个元素,添加到一个字典中
最终获得类似{"A1":5,"A3":2,"D1":5,"D3":10}的字典,也就是记录每一个元素出现的次数,如果是10个元组的交集,那么次数=10。
⑶ 求两个集合交集的算法
我这里有一个很强的,是以前的作业,功能有很多!
有问题来找小斌
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');
}
⑷ 如何计算两个有序整型数组的交集
例如,两个含有n个元素的有序(非降序)整形数组a和b(数组a和b中都没有重复元素),求出其共同元素。
a[]={0,1,2,3,4};
B[]={1,3,5,7,9};
那么它们的交集为{1,3}。
计算数组交集可以采用很多种方法,但数组的相对大小一般会影响算法的效率,所以需要根据两个数组的相对大小来确定采用的方法。
(1)对于两个数组长度相当的情况,一般可以采取以下3种方法。
方法一:采用二路归并来遍历两个数组。(这个名字好霸气,有木有武功招数的赶脚)
设两个数组分别为array1[n1]和array2[n2],分别以i、j从头开始遍历两个数组。在遍历过程中,如果当前遍历位置的array1[i]与array2[j]相等,则此数为两个数组的交集,记录到随便array1或array2中,并继续向后遍历array1和array2.如果array1[i]>array2[j],则需继续向后遍历array2.如果array1[i]小于array2[j],则需要继续向后遍历array1,直到有一个数组结束遍历即停止。总的来说,就是谁落后了,谁的下标就自增去吧。
代码如下:
#include "stdafx.h"
#include <stdio.h>
void mixed(int array1[], int n1, int array2[], int n2)
{
int i = 0, j = 0, k = 0;
while (i < n1&&j < n2)
{
if (array1[i] == array2[j])
{
array1[k] = array1[i];
printf("%d\n", array1[k]);
i++;
j++;
k++;
}
else if (array1[i]>array2[j])
{
j++;
}
else if (array1[i] < array2[j])
{
i++;
}
}
}
void main()
{
int a[] = { 0, 1, 2, 3, 4 };
int b[] = { 1, 3, 5, 7, 9 };
mixed(a, 5, b, 5);
getchar();
}
效果如图:
方法二:顺序遍历两个数组,将数组元素存放到哈希表中,同时对同级的数组元素进行计数。如果为2,则为两者的交集元素。
方法三:遍历两个数组中任意一个数组,将遍历得到的元素存放到哈希表,然后遍历另外一个数组,同时对建立的哈希表进行查询,如果存在,则为交集元素。
(2)对于两个数组长度相差悬殊的情况,如数组a的长度远远大于数组b的长度,则可以采用下面几种方法。
方法一:依次遍历长度小的数组,将遍历得到的数组元素在长数组中进行二分查找。具体而言,设两个指向两个数组为元素的指针,取较小的那个数在另一个数组中二分查找,找到,则存在一个交集,并且将该目标数组的指针指向该位置前一个位置。如果没有找到,同样可以找到一个位置,使得目标数组中在该位置后的数肯定不在另一个数组中存在,直接移动该目标数组的指针指向该位置的前一个位置,再循环找,直到一个数组为空为止。因为两个数组中都可能出现重复的数,因此二分查找时,当找到一个相同的数x时,其下标为i,那么下一个二分查找的下界变为i+1,避免x重复使用。
方法二:采用与方法一类似的方法,但是每次查找在前一次查找的基础上进行,这样可以大大缩小查找表的长度。
方法三:采用与方法二类似的方法,但是遍历长度小的数组的方式有所不同,从数组头部和尾部同时开始遍历,这样可以进一步缩小查找表的长度。
⑸ 集合的交集与并集
【补充:A∩D={直角三角形},B∩D={等腰直角三角形}】
交集就是既要属于A又要属于B,且的关系,类似于算法中的乘法,
而并集是属于A或者属于B,或的关系,类似于算法中的加法。
已知集合A={三角形},B={等腰三角形},C={等边三角形},D={直角三角形},那么A交B,B并C,C交D,A并D,B交C,B并D。
解:
A∩B={等腰三角形},
B∪C={等腰三角形},
C∩D=空集
A∪D={三角形}
B∩C={等边三角形}
B∪D={等腰三角形和直角三角形}
⑹ 大数据量的交集,并集,差集求解算法
首先这点数据并不大呀。。
交集最好做 [hash]/[单排序+二分]/[双排序+归并过程找]
并集同理,只不过把交集中不要的数据也记录下来就行了
差集,只要交集过程中不要的