設計算法,求AB兩個整數集合的交集


【本文鏈接】

http://www.cnblogs.com/hellogiser/p/ab-set-intersection.html

【分析】

思路1:排序法

  對集合A和集合B進行排序(升序,用快排,平均復雜度O(N*logN)),設置兩個指針p和q,同時指向集合A和集合B的最小值,不相等的話移動*p和*q中較小值的指針,相等的話同時移動指針p和q,並且記下相等的數字,為交集的元素之一,依次操作,直到其中一個集合沒有元素可比較為止。

  優點:操作簡單,容易實現。

  缺點:使用的排序算法不當,會耗費大量的時間,比如對排好序的集合使用快排, 時間復雜度是O(N2)

  這種算法是大家都能比較快速想到的辦法,絕大多數時間放在了對集合的排序上,快排的平均復雜度是O(N*logN),對排好序的集合做查找操作,時間復雜度為O(N),當然這種算法肯定比遍歷要快多了。

【代碼】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 
/*
version: 1.0
author: hellogiser
blog: http://www.cnblogs.com/hellogiser
date: 2014/10/8
*/


#include   "stdafx.h"
#include  <iostream>
using   namespace  std;


int  cmp( const   void  *a,  const   void  *b)
{
    
int  *x = ( int  *)a;
    
int  *y = ( int  *)b;
    
return  (*x) - (*y);
}

void  intersection( int  *A,  int  M,  int  *B,  int  N)
{
    
// quick sort
    qsort(A, M,  sizeof ( int ), cmp);
    qsort(B, N, 
sizeof ( int ), cmp);
    
int  i =  0 , j =  0 ;
    
int  cnt =  0 ;
    
int  *result =  new   int [M > N ? M : N]; // save result
     while (i < M && j < N)
    {
        
if (A[i] == B[j])
        {
            result[cnt++] = A[i];
            i++;
            j++;
        }
        
else   if (A[i] < B[j])
        {
            i++;
        }
        
else
        {
            j++;
        }
    }

    
//output result
     for (i =  0 ; i < cnt; i++)
    {
        printf(
"%4d" , result[i]);
    }

    
delete  []result;
}

void  test_case()
{
    
int  A[] = { - 1 2  ,  39  ,  10 6 11 188 10 };
    
int  len1 =  sizeof (A) /  sizeof ( int );
    
int  B[] = { 39  ,  8  ,  10 6 , - 1 };
    
int  len2 =  sizeof (B) /  sizeof ( int );
    intersection(A, len1, B, len2);
}

int  main()
{
    test_case();
    
return   0 ;
}

思路2:索引法

(本質是Bitset方法,要求集合所有數據在【0,range】之內)

以空間換時間,把集合中的元素作為數組下表的索引。來看例子:      

A= {1 ,12, 13, 25},那Asub[1] = 1,Asub[12] = 1 ,Asub[13] = 1 ,Asub[25] = 1 ;

B={1, 2,  3, 15 ,}那Bsub[1] = 1; Bsub[2] = 1; Bsub[3] = 1; Bsub[15] = 1;

  對元素少的集合掃一遍,發現Asub[1] = 3 和Bsub[1] = 1有相同的索引1,並且重復度為1,所以交集肯定包括{1, 1}; Bsub[2] = 1而Asub[2] = 0,表示無交集,依次類推,可以得到集合A和B的交集。

  假設集合中存在負數,可以把集合分成正整數和負整數(加個負號變正整數)兩部分,解法同上!

  優點:速度快,時間復雜度O(N)

  缺點:空間消耗大,以空間換取時間

【擴展】

  給定兩個整數集合A和B,每個集合都包含20億個不同整數,請給出快速計算A∩B的算法,算法可使用外存,但是要求占用內存不能超過4GB。

  將集合A的整數,根據n%10不同,分別裝入10個文件中,依次命名為a0,a1……,a9。同理,將集合B分別裝入10個文件中,依次命名為b0,b1,……,b9。那么A和B編號不同的文件中,一定不會有相同的整數。只需分另求出a0與b0中共有的元素、a1與b1中共有的元素……。
  利用bitmap,將bitmap清0,讀入文件ai,依次處理每個數,即將bitmap的第(n/10)位置1。然后讀入文件bi,依次處理每個數,即:若bitmap第(n/10)位為1,則這個數屬於A∩B。

http://www.cnblogs.com/sooner/p/3280050.html

【參考】

http://blog.csdn.net/jie1991liu/article/details/13168255


免責聲明!

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



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