求两个数组的交集
题目意思大概是这样的:给定两个大数组(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。