zoukankan      html  css  js  c++  java
  • 求两个数组的交集

    求两个数组的交集

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

  • 相关阅读:
    倒计时浏览器跳转JavaScript
    C#.NET中使用存储过程的方法及其优点
    利用GridView控件导出其他文件(导出Excel,导出Word文件)
    c#.net用JavaScript实现 时钟显示
    程序执行一半后可以跳出对话框选择是否继续执行
    FreeMarker 中文官方参考手册 For Freemarker 2.3.23
    Spring技术内幕之Spring Data JPA-自定义Repository实现
    ehcache入门基础示例
    SpringData JPA 接口和方法
    Springboot中使用缓存
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3332710.html
Copyright © 2011-2022 走看看