交集演算法
⑴ 並集和交集的公式是什麼
交集?並集?
你還記得高中數學的第一課嗎?講的是集合,具體定義去網路,裡面有兩個運演算法則:交集和並集。也許你當時覺得很容易,那麼今天還是回頭想想它在講什麼。
一、兩個集合
一切運算都是兩個相對的集合間的關系法則,既然是高中數學,那麼就略談一下教育,其實很多人會說「你考好了說明學好了」,然而我想說的是考試和教學是兩個集合。
我們看看中國過去的八股文,包括今天的高考,受到那麼多詬病,但是為什麼還是繼續這么做?因為相關部門不知道,無作為?我覺得要是從另外一個角度看,考試作為一種人才選拔的工具,那選拔什麼樣的人呢?是見多識廣、才華橫溢的人;還是那些面對一個目標,能持之以恆地找方法達成,坐得住、能下功夫的人呢?
不好意思,答案很可能是後者。
現在很多創業公司都有這樣的體會。招人的時候,他們往往不是傾向於招那些有經驗的人,而傾向學習能力好、溝通能力強、對自己要求嚴、有自我驅動能力的人。因為創業公司本來做的就是全新的事情,經驗這個東西是有益還是有害,說不清楚。但是面對任何新的情況,都能找到方法、訴諸行動、不丟目標的人,才是創業公司需要的。前一陣還有一位創業公司的創始人跟我說,他發現優秀的大學生,比行業里的老鳥好用。
這種優秀的人,不管面對什麼樣的題目,哪怕是八股文,也一樣可以坐得住、下苦功,最後考出好成績。這樣的人走入仕途,面對自己不熟悉的任務,也一樣會表現優秀。事實上,明清兩代那麼多能人都是靠八股文選拔出來的,比如我們熟悉的王陽明和曾國藩。
再回頭來說我們的高考。
這幾年,高考的發展趨勢和八股文正好相反的,這也是很多人呼籲和推動的結果。各地高考越來越強調地方特色,越來越多地考核學生的所謂「綜合素質」。這種發展方向看似正確,但是也有值得反思的地方。
首先,中國是一個大國,各地情況差異巨大,社會階層也差異巨大。只有堅持全國的統一性,才能確保人才通過高考在全國范圍內的流動和交流,維持整個國家的內在聯系和國家認同。不誇張地說,如果高考的全國統一性消失了,中國各個地方的內在聯系會被嚴重削弱。
我們不能把高考僅僅看作是教育的一個環節,高考是國家治理中的關鍵,事關國家的完整統一和治理水平。
其次,雖然不必恢復到八股文那樣死板的形式,但高考仍然要盡量維持簡單、明晰的考試內容和形式。一言以蔽之,永遠要確保,學生只靠幾本教科書、只比拼硬功夫、笨功夫就能取得好成績。
和科舉一樣,高考不是教育工具,高考是人才選擇的工具。它把各個社會階層里奮發向上,能坐得住、下苦功夫的人挑選出來,保持這個社會的活力和公平。這才是高考在當前中國社會的真實作用。
然而,所謂教育則是一種能力的培養,一種思維模式的鍛煉,比如我們講集合,你不光會做題還要會應用,比如將學習數學思維和考試分開來,當然它們之間有交集,就是你既能坐下來刷題總結,又能進行發散和轉化,你要既能學好集合又能考好集合這就是交集,而你只是明白自己要好好學習並且考試優異這就是並集。其實大多數人在看問題的時候喜歡用並集,這樣比較省事,也符合原始的認知方式,然而今天這種方式與時代有所不匹配啦,這種人就是那些現在邊緣只求安全感,卻不願多向集合內多走一步深入了解的人。我們在許多問題上可以有所區分,比如人工智慧就是未來一切的引導?關系問題一定是其中一個人有問題或者兩個人有問題?
二、人工智慧就是人類的全部模擬?
這個的答案明顯是否定的,人工智慧是完全通過演算法運行的,這些演算法都來自於各個學科的模型計算,你去翻翻書,所以學科都有一個所謂的理想假設,這個假設通俗的講就是,如果世界只有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]/[單排序+二分]/[雙排序+歸並過程找]
並集同理,只不過把交集中不要的數據也記錄下來就行了
差集,只要交集過程中不要的