【本文鏈接】
http://www.cnblogs.com/hellogiser/p/ab-set-intersection.html
【分析】
思路1:排序法
對集合A和集合B進行排序(升序,用快排,平均復雜度O(N*logN)),設置兩個指針p和q,同時指向集合A和集合B的最小值,不相等的話移動*p和*q中較小值的指針,相等的話同時移動指針p和q,並且記下相等的數字,為交集的元素之一,依次操作,直到其中一個集合沒有元素可比較為止。
優點:操作簡單,容易實現。
缺點:使用的排序算法不當,會耗費大量的時間,比如對排好序的集合使用快排, 時間復雜度是O(N2)
這種算法是大家都能比較快速想到的辦法,絕大多數時間放在了對集合的排序上,快排的平均復雜度是O(N*logN),對排好序的集合做查找操作,時間復雜度為O(N),當然這種算法肯定比遍歷要快多了。
【代碼】
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/10/8 */ #include "stdafx.h" #include <iostream> using namespace std; int cmp( const void *a, const void *b) { int *x = ( int *)a; int *y = ( int *)b; return (*x) - (*y); } void intersection( int *A, int M, int *B, int N) { // quick sort qsort(A, M, sizeof ( int ), cmp); qsort(B, N, sizeof ( int ), cmp); int i = 0 , j = 0 ; int cnt = 0 ; int *result = new int [M > N ? M : N]; // save result while (i < M && j < N) { if (A[i] == B[j]) { result[cnt++] = A[i]; i++; j++; } else if (A[i] < B[j]) { i++; } else { j++; } } //output result for (i = 0 ; i < cnt; i++) { printf( "%4d" , result[i]); } delete []result; } void test_case() { int A[] = { - 1 , 2 , 39 , 10 , 6 , 11 , 188 , 10 }; int len1 = sizeof (A) / sizeof ( int ); int B[] = { 39 , 8 , 10 , 6 , - 1 }; int len2 = sizeof (B) / sizeof ( int ); intersection(A, len1, B, len2); } int main() { test_case(); return 0 ; } |
思路2:索引法
(本質是Bitset方法,要求集合所有數據在【0,range】之內)
以空間換時間,把集合中的元素作為數組下表的索引。來看例子:
A= {1 ,12, 13, 25},那Asub[1] = 1,Asub[12] = 1 ,Asub[13] = 1 ,Asub[25] = 1 ;
B={1, 2, 3, 15 ,}那Bsub[1] = 1; Bsub[2] = 1; Bsub[3] = 1; Bsub[15] = 1;
對元素少的集合掃一遍,發現Asub[1] = 3 和Bsub[1] = 1有相同的索引1,並且重復度為1,所以交集肯定包括{1, 1}; Bsub[2] = 1而Asub[2] = 0,表示無交集,依次類推,可以得到集合A和B的交集。
假設集合中存在負數,可以把集合分成正整數和負整數(加個負號變正整數)兩部分,解法同上!
優點:速度快,時間復雜度O(N)
缺點:空間消耗大,以空間換取時間
【擴展】
給定兩個整數集合A和B,每個集合都包含20億個不同整數,請給出快速計算A∩B的算法,算法可使用外存,但是要求占用內存不能超過4GB。
將集合A的整數,根據n%10不同,分別裝入10個文件中,依次命名為a0,a1……,a9。同理,將集合B分別裝入10個文件中,依次命名為b0,b1,……,b9。那么A和B編號不同的文件中,一定不會有相同的整數。只需分另求出a0與b0中共有的元素、a1與b1中共有的元素……。
利用bitmap,將bitmap清0,讀入文件ai,依次處理每個數,即將bitmap的第(n/10)位置1。然后讀入文件bi,依次處理每個數,即:若bitmap第(n/10)位為1,則這個數屬於A∩B。
http://www.cnblogs.com/sooner/p/3280050.html
【參考】