2009-08-11 120 views
2

我有2個數組(AB),其中包含有些差異的相似數據。我想返回僅在A中的對象數組和僅在B中的另一個對象數組。到目前爲止,我一直在想:比較算法

  1. 一些優化蠻力(這是微不足道的)
  2. 排序的陣列和使用二進制搜索。

我的其他選擇是什麼?任何語言/解決方案都是公平遊戲。

回答

6

您可以對兩個數組進行排序,然後同時對兩個數組進行線性掃描。這將是用於排序的O(nlogn)算法和用於掃描/建立新陣列的O(n)。

0

嘗試使用集合。他們通常有一個差異()方法(或類似的東西),返回到你想要的。就那麼簡單。一旦語言不可知,如何創建集合或將差異轉換爲數組就是使用一般方法完成的。

Set A = createSetA(); 
Set B = createSetB(); 

Array onlyAElements = transformToArray(A.difference(B)); 
Array onlyBElements = transformToArray(B.difference(A)); 

或者,您可以對兩個數組進行排序,並同時獲取兩個差異數組。類似於

int aIndex = 0; 
int bIndex = 0; 

Array aOnly = new Array(); 
Array bOnly = new Array(); 

while (aIndex != a.length || bIndex != b.length) 
{ 
    if (A[aIndex] == B[bIndex] 
    { 
     aIndex++; 
     bIndex++; 
    } 
    else if (A[aIndex] > B[bIndex]) 
    { 
     aOnly.add(A[aIndex]); 
     aIndex++; 
    } 
    else 
    { 
     bOnly.add(B[bIndex]); 
     bIndex++; 
    } 
} 

您應該記住在越界時出現一些錯誤。但代碼只是爲了得到主要想法。

+0

正是我要說的。例如Python的sets模塊,你可以使用差異()或簡單的「 - 」運算符。 http://docs.python.org/library/sets.html – MatrixFrog 2009-08-11 02:51:10

+0

我認爲他正在尋找隱藏的算法。這裏有很多簡單的單行(想想LINQ),但是他們真的沒有教我們什麼,我們不知道沒有閱讀文檔,他們的效率是什麼。 – JoshJordan 2009-08-11 02:51:11

+0

我知道的兩套算法是哈希集合和樹集合。 Google或SO搜索這些條款。 – MatrixFrog 2009-08-11 02:53:30

0

我沒有實現或算法超越什麼的已經說過,但我想我會留在C#/ LINQ該解決方案的人誰可能會發現這個問題,並要做到這一點:

var a = new int[] { 1, 2, 3, 6, 7, 8, 9, 10 }; 
    var b = new int[] { 1, 2, 3, 4, 5, 6, 7 }; 

    int[] addedToA = a.Except(b); 
    int[] missingFromA = b.Except(a); 

    foreach (var i in addedToA) 
    { 
     Console.Write("{0} ", i); 
    } 
    Console.WriteLine(); 
    foreach (var i in missingFromA) 
    { 
     Console.Write("{0} ", i); 
    } 

這將打印:

8 9 10 
4 5 
1

很多這將取決於你有什麼類型的數據。你提到排序,所以我認爲它的元素是可比的。隨着套尺寸mn,這將需要進行排序,這將佔主導地位。 (漸近地說,如果你進行二分搜索或者走這兩個列表都沒有關係,走這兩個列表應該是O(m + n)。)當然,如果你正在使用更好的排序算法可用的數據,比如帶有基數排序的整數,你應該可以降到O(m + n)

使用集合(正如其他人所暗示的)隱含地建議使用散列,這肯定會使您的問題更容易。如果散列A中的所有元素(O(m)),並將散列集中的所有散列存儲在內存中,則散列B(O(n))並檢測散列集中可能發生衝突的位置。這成爲優化的問題:您必須評估經典的速度 - 內存摺衷。散列集越大,碰撞檢查的速度就越快。這將在O(m + n)中運行。

值得注意的是,你可以證明任何你要求的算法至少會在至少m + n時間內運行,因爲需要查看所有的輸入。

+0

@David:在比較排序與散列表方法時,您還需要考慮1)散列函數計算的代價與比較成本(針對不等於的情況進行優化)以及2)散列函數是否給出一個很好的傳播。 – 2009-08-11 03:40:49

+0

@Stephen絕對!我不想考慮這些考慮因素,因爲它們往往需要對我們沒有的投入進行假設。 – 2009-08-13 00:43:03

2

我想將數組A的元素填充到散列表中,然後遍歷數組B在哈希表中進行查找以有效地確定B中的哪些元素也在A.然後在遍歷數組A的同時在散列表中對B的元素執行同樣的操作。這將始終是O(N)。

+0

哈希表往往會生成更快的算法,但通常會佔用大部分內存。順便說一句好的答案 – 2009-08-11 03:24:40