2015-04-04 107 views
1

這是我的第一個問題,所以我希望我做對了。
我要創建整數陣列的列表:以存儲與N個數K中的元素的所有組合搜索列表中的現有對象

List<int[]> finalList = new List<int[]>(); 

例如:

N=5, K=2 => {1,2},{1,3},{1,4},... 

一切都是正確的,但我想避免的名單({1,2}{2,1}例如)同一組合的重複。因此,在將tmpArray(其中我臨時存儲新組合)添加到列表中之前,我想檢查它是否已經存儲。

這是我在做什麼:

  • 下一個組合(OK)
  • 排序tmpArray(OK)
  • 檢查創建tmpArray如果列表中已經包含tmpArray具有以下代碼:

    if (!finalList.Contains(tmpArray)) 
        finalList.Add(tmpArray); 
    

,但它不工作。任何人都可以幫我解決這個問題嗎?

+0

你考慮避免在首位的重複?例如。只添加n1 CompuChip 2015-04-04 15:30:36

回答

1

Array是一個引用類型 - 你的Contains查詢不會做你想做的(比較所有成員的順序)。

你可以使用這樣的事情:

if (!finalList.Any(x => x.SequenceEqual(tmpArray)) 
{ 
    finalList.Add(tmpArray); 
} 

(請確保您添加using System.Linq到文件的頂部)

我建議你瞭解value vs. reference types,LINQ和C#的數據結構基礎。儘管上面的查詢應該可以工作,但它會很慢 - O(n * m)其中n =每個陣列的finalListm長度中的數組數量。

對於較大的數組,某些預計算(例如每個數組的哈希碼)允許您進行更快速的比較可能會有所幫助。

+0

當我更多地瞭解可以完成許多不同事情的Linqs和Lambda表達式時,我越來越驚訝。你的例子是否與TakeWhile()相似?我以前用它來做數組比較。 – Shar1er80 2015-04-04 14:54:01

+0

@ Shar1er80類似的,它遍歷一個枚舉,是的 - 否則不同 – BrokenGlass 2015-04-04 16:10:19

0

如果我沒有記錯,包含將檢查值數據類型的值,或者它將檢查對象類型的地址。一個數組是一個對象類型,所以這個contains只檢查內存中的地址是否存儲在你的列表中。您必須檢查此列表中的每個項目並執行某種類型的算法以檢查數組值是否在列表中。

Linq,Lambda或蠻力檢查浮現在腦海。

BrokenGlass對Linq和Lambda給出了一個很好的建議。

蠻力:

bool itemExists = true; 
foreach (int[] ints in finalList) 
{ 
    if (ints.Length != tmpArray.Length) 
    { 
     itemExists = false; 
     break; 
    } 
    else 
    { 
     // Compare each element 
     for (int i = 0; i < tmpArray.Length; i++) 
     { 
      if (ints[i] != tmpArray[i]) 
      { 
       itemExists = false; 
       break; 
      } 
     } 

     // Have to check to break from the foreach loop 
     if (itemExists == false) 
     { 
      break; 
     } 
    } 
} 

if (itemExists == false) 
{ 
    finalList.add(tmpArray); 
} 
+1

有一個'Contains'的重載,它需要'IEqualityComparer'來進行比較。如果沒有提供,則使用默認的相等比較器,其語義如下所述:https://msdn.microsoft.com/en-us/library/vstudio/ms224763(v=vs.100).aspx。 – 2015-04-04 15:09:13