求两个数组的交集

求两个数组的交集

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

 

 

 

 

 

分类: C/C++

原文地址:https://www.cnblogs.com/Leo_wl/p/3332710.html