求兩個數組的交集


題目意思大概是這樣的:給定兩個大數組(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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM