大数据---集合交集和并集

1.有两个大数据 Array1和数组Array2:求两个数组的交集:

  •    1).时间复杂度o(N*M) 空间复杂度o(1);
 1 public static void test1(int array1[],int array2[])
 2     {// 暴力解法
 3         List<Integer> E=new ArrayList<>();
 4         for(int i=0;i<array1.length;i++)
 5             for(int j=0;j<array2.length;j++)
 6             {
 7                 if(array2[j]==array1[i])
 8                     E.add(array2[j]);
 9             }
10                 
11     }
  •  2). 双排序后进行比较 排序完毕后 如果array1[index1]>array2[index2] 则index2++; 否则的话index1++ ,相同的话将其放入到容器ArrayList中

算法复杂度分析 排序(桶排序算法时间复杂度 o(MlogM) )+遍历的时间= o(N*log(N)+M*log(M))+o(min(N,M)) 对其进行进一步的理解:

 1 public static void test2(int array1[],int array2[])
 2     {
 3         
 4         //1.使用快速排序
 5         quick(array1,0,array1.length-1);// 使用Arrays数组中的方法
 6         
 7        //2.使用Arrays数组中sort方法---使用快速排序
 8         Arrays.sort(array2);
 9         
10         
11         List<Integer> E=new ArrayList<>();
12         
13         int index1=0,index2=0;
14         int length=Math.min(array1.length,array2.length);
15      while(index1<length && index2<length)
16      {
17          if(array1[index1]==array2[index2])
18          {
19              E.add(array1[index1]);
20              index1++;index2++;
21          }
22          else if(array1[index1]>array2[index2])
23              index2++;
24          else
25              index1++;
26      }
27      
28      for(int i=0;i<E.size();i++)
29          System.out.print(E.get(i)+" ");
30     }

对快速排序的方法:

 1 public static void quick(int array[],int low,int hight)
 2     {//叫做 挖坑填补+分治法
 3          if(low<hight)
 4          {
 5              int middle=getMiddle(array,low,hight);
 6              quick(array,low,middle-1);// 对低的表进行递归
 7              quick(array,middle+1,hight);//对较高的表进行递归
 8          }
 9     }
10     public static int getMiddle(int array[],int start,int end)
11     {//一次遍历下来 Key小的在前方,比Key值大在后面
12          int temp=array[start];
13          while(start<end)
14          {
15              while(start<end && array[end]>temp)
16                  end--;
17              array[start]=array[end];
18              
19              while(start<end && array[start]<temp)
20                  start++;
21              array[end]=array[start];
22              
23          }
24          array[start]=temp;
25          return start;
26     }
  • 3)使用哈希表:将两组数据放入到哈希表中,最后只需要变量哈希集合就可以得到:空间o(N+M) 时间复杂度o(N+M)
  • 当然这些解决冲突封装在hashMap,HashTable 中

在数据散列的时候 有两种方法解决冲突Hash=x mod N ; 集合中的数据随机的,不同的随机数散列到同一个地址,不得不解决位置冲突

      第一种分离链接法:在产生冲突时候 使用LinkedList存取冲突的数据:一般表的大小选择 接近o(N+M)最近的素数

     第二种:开放地址方法:装填因子<=0.5 超过不得不扩大表的大小2*TableSize+1,一旦发生冲突:使用线性方法,或者平方的方法大的数据表中 找新的位置来解决冲突

 1 public static void test3(int array1[],int array2[])
 2     {
 3         // 通过HashMap:求两个集合中交集
 4         Map<Integer,Integer> map=new HashMap<>();
 5         
 6         for(int i=0;i<Math.min(array1.length,array2.length);i++)
 7         {
 8             contains(map,array1[i]);
 9             contains(map,array2[i]);
10         }
11         
12         // 遍历
13         for(Map.Entry<Integer, Integer>m:map.entrySet())
14         {
15             if(m.getValue()>1)
16                 System.out.println(m.getKey());
17         }
18     }
19     
20     public static void contains(Map<Integer,Integer>map,int k)
21     {
22         if(map.containsKey(k))
23         {
24             int tmp=map.get(k);
25             tmp++;
26             map.put(k, tmp);
27         }
28         else
29         {
30             map.put(k,1);
31         }
32     }

当数据集特别大的时候可以使用MapReduce的过程的处理,Mapreduce 的原理是一个归并排序---使用数据量大但是数据种类小的

用N个Map任务和一个reduce任务,对原始数据进行分组,通过hash(item)%N将数组中的数据分到各个Map任务中

每个MAp任务求每个子集的交集处理。

  归并排序:将两个以上的有序表合并成一个新的有序表,可以用于内排序同时运用于外排序 一种稳定的排序方式,无论最好还是最坏的情况O(NlogN),辅助空间o(N)

 1 public static void contains(Map<Integer,Integer>map,int k)
 2     {
 3         if(map.containsKey(k))
 4         {
 5             int tmp=map.get(k);
 6             tmp++;
 7             map.put(k, tmp);
 8         }
 9         else
10         {
11             map.put(k,1);
12         }
13     }
14     
15     public static void Merger_sort(int array[],int start,int end)
16     {
17         if(start>=end)
18             return;
19         int Mid=(start+end)/2;
20         
21         Merger_sort(array,start,Mid);
22         Merger_sort(array,Mid+1,end);
23         int[]m=Merger(array,start,Mid,end);
24         
25         for(int i=0;i<m.length;i++)
26         {
27             System.out.println(m[i]);
28         }
29         System.out.println();
30     }
31 
32     private static int[] Merger(int[] a, int left, int mid, int right) {
33         int r1=mid+1;
34         int tmp[]=new int[a.length];
35         
36         int tIndex = left;
37         int cIndex=left;
38         // 逐个归并
39         while(left <=mid && r1 <= right) {
40             if (a[left] <= a[r1]) 
41                 tmp[tIndex++] = a[left++];
42             else
43                 tmp[tIndex++] = a[r1++];
44         }
45             // 将左边剩余的归并
46             while (left <=mid) {
47                 tmp[tIndex++] = a[left++];
48             }
49             // 将右边剩余的归并
50             while ( r1 <= right ) {
51                 tmp[tIndex++] = a[r1++];
52             }
53             
54             int i=0;
55             System.out.println("第"+(++i)+"趟排序:	");
56             // TODO Auto-generated method stub
57             //从临时数组拷贝到原数组
58              while(cIndex<=right){
59                     a[cIndex]=tmp[cIndex];
60                     //输出中间归并排序结果
61                     System.out.print(a[cIndex]+"	");
62                     cIndex++;
63                 }
64              System.out.println();
65         return a;
66     }
原文地址:https://www.cnblogs.com/woainifanfan/p/6723516.html