題目意思大概是這樣的:給定兩個大數組(1w以上1億以下),用最有效的方法找出來兩個數組的交集。
對於這道題,我有一個思路就是,先對數組進行排序,然后用兩個指針在已排序的數組上輪流指向頭結點,進行比較。
比較亮的地方,就是在於這個比較的方式了。
首先,比較的時候,要先確定兩個指針指向的內用是否一致。如果一致,那么這個點,就是交集的一個元素,沒問題吧?
這里有一個問題就是,接下來如何比較?
步驟是這樣的:先比較兩個指針指向內容的大小,指向結果小的指針,開始遞增,直到較小的指針指向的值大於或等於另一個指針。
而接下來另一個指針也采用同樣的方法,此時這個較大的指針已經變成了較小的指針,遞增,直到比大於或等於另一個指針。
上面兩輪比較完成后,如果指向的值相等,那么,保存這個數據,同時進行相同數據的處理,代碼中會有體現。
然后兩個指針++,接着進行下一輪比較就可以了。
采用這種方法,就能夠求出兩個大數組的交集,效率還是不錯的。如果兩個數組的長度分別為m和n,算上快排所需的時間,那么總時間效率為:
O(nlog(n) + mlog(m) + m + n)應該說還不錯。
空間效率則為O(1)//不算交集的數據存儲
首先說下:如果你覺得代碼中出現了英文注釋就覺得代碼不是我寫的,那么我只能說:你out了~
其實主要的原因還是方便,而且codeblocks上的漢子很難看……
另外我的這個代碼先用一個程序生成了兩個比較大的隨機數據文件,個數分別是1w和2w。隨機數據文件生成代碼如下:
1 #include <iostream> 2 #include <fstream> 3 #include <vector> 4 #include <cstdlib> 5 #include <ctime> 6 7 using namespace std; 8 9 int main() 10 { 11 cout << "Hello world!" << endl; 12 ofstream fout; 13 vector<int> ArrayOne; 14 vector<int> ArrayTwo; 15 int n = 10000; 16 int m = 20000; 17 srand(time(NULL)); 18 for(int i = 0;i < n;++ i) 19 ArrayOne.push_back(rand()); 20 for(int i = 0;i < m;++ i) 21 ArrayTwo.push_back(rand()); 22 fout.open("A.txt", ios_base::out | ios_base::trunc); 23 for(int i = 0;i < n;++ i) 24 fout << ArrayOne[i] << ends; 25 fout.close(); 26 27 fout.open("B.txt", ios_base::out | ios_base::trunc); 28 for(int i = 0;i < m;++ i) 29 fout << ArrayTwo[i] << ends; 30 fout.close(); 31 return 0; 32 }
算法代碼,我沒有函數化,畢竟操作有限,而且思路簡單。
1 #include <iostream> 2 #include <fstream> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 int main() 9 { 10 cout << "Hello world!" << endl; 11 //find the same value in the two big array! 12 ifstream fin; 13 vector<int> ArrayOne, ArrayTwo; 14 vector<int> ResultArray; 15 int tmpVal; 16 char tmpChar; 17 fin.open("A.txt", ios_base::in); 18 while(1) 19 { 20 fin >> tmpVal; 21 fin >> tmpChar; 22 if(fin.fail()) 23 break; 24 ArrayOne.push_back(tmpVal); 25 } 26 fin.close(); 27 28 fin.open("B.txt"); 29 while(1) 30 { 31 fin >> tmpVal; 32 fin >> tmpChar; 33 if(fin.fail()) 34 break; 35 ArrayTwo.push_back(tmpVal); 36 } 37 fin.close(); 38 39 //sort first 40 sort(ArrayOne.begin(), ArrayOne.end()); 41 sort(ArrayTwo.begin(), ArrayTwo.end()); 42 43 const int nSize1 = ArrayOne.size(); 44 const int nSize2 = ArrayTwo.size(); 45 //cmp job 46 int nPointer1 = 0; 47 int nPointer2 = 0; 48 while(nPointer1 < nSize1 && nPointer2 < nSize2) 49 { 50 while(ArrayOne[nPointer1] < ArrayTwo[nPointer2]) 51 { 52 nPointer1 ++; 53 } 54 while(ArrayOne[nPointer1] > ArrayTwo[nPointer2]) 55 { 56 nPointer2 ++; 57 } 58 if(ArrayOne[nPointer1] == ArrayTwo[nPointer2]) 59 { 60 int tmpVal = ArrayOne[nPointer1]; 61 ResultArray.push_back(ArrayOne[nPointer1]); 62 while(ArrayOne[nPointer1] == tmpVal) 63 nPointer1++; 64 while(ArrayTwo[nPointer2] == tmpVal) 65 nPointer2++; 66 } 67 nPointer1++; 68 nPointer2++; 69 } 70 71 int nResultLength = ResultArray.size(); 72 ofstream fout; 73 fout.open("Result.txt", ios_base::out | ios_base::trunc); 74 for(int i = 0;i < nResultLength;++ i) 75 { 76 fout << ResultArray[i] << ends; 77 } 78 fout.close(); 79 return 0; 80 }
這兩段代碼可以在計算機上運行一下,還是很簡單的,另外上面的代碼在數據相等的時候專門進行了重復數據的排查。
不過,這個程序我只是簡單的驗證了一下,不排除存在bug。