2012-12-01 113 views
2

我有五個不同長度的數組,我需要遍歷所有這些數組,以生成所有可能的內容組合。我目前使用5嵌套的for循環,像這樣:C# - 最有效的方法來遍歷多個數組/列表

for (int a = 1; a < Array1.Length - 1; a++) 
    { 
    for (int b = 1; b < Array2.Length - 1; b++) 
     { 
     for (int c = 1; c < Array3.Length - 1; c++) 
      { 
      for (int d = 1; d < Array4.Length - 1; d++) 
       { 
       for (int e = 1; e < Array5.Length - 1; e++) 
        { 
        //do something 
        } 
       } 
      } 
     } 
    } 

由於數組的大小,我結束了超過4.56億次迭代。一般來說,我對編程相當陌生,特別是C#。我只是好奇,如果有更高效的方式來實現這一點。

謝謝。

+7

問:爲什麼「需要遍歷全部內容以生成所有可能的內容組合」? –

+6

同樣,循環中的計數器應該從0開始(c#使用基於零的索引),然後上升到Length('counter

+2

無論代碼如何顯示, 4.56億個組合,將會有456個全部元素的迭代。 – jcolebrand

回答

5

你經歷了很多次迭代,因爲有很多組合:這叫做combinatorial explosion。如果你必須經歷所有可能的組合,你不能更有效地做到這一點。

通過使用遞歸,您可以使用較少的代碼行編碼,也可以不使用硬編碼陣列數(在您的案例中爲五個)。但是,迭代次數不會改變,只有代碼行數。

void processCombination(int[] combination) { 
    // combination[i] has the index of array #i 
    ... 
} 
void combine(int p, int[] indexes, int[] sizes) { 
    if (p == indexes.Length) { 
     processCombination(indexes); 
    } else { 
     for (indexes[p] = 0 ; indexes[p] != sizes[p] ; indexes[p]++) { 
      combine(p+1, indexes, sizes); 
     } 
    } 
} 
+1

那麼,這不是真的。如果他知道編譯器沒有的東西,他可以展開一些循環/命令它們有利於緩存,但是這種改進可能很小。 – sybkar

+1

+1。直接迭代數組(具有正確的範圍:))在C#中絕對是最有效的方法。 (456M項目的實用性值得懷疑,但問題並非如此)。 –

+0

另一點:如果在C#中迭代數組從0到array.length(正如問題中的示例所做的那樣,或多或少),抖動將刪除索引上的邊界檢查,從而提高性能在保持邊界檢查的情況下約爲3倍。 – mydogisbox

相關問題