2016-07-08 170 views
0

有一個m×n的數組,我需要輸出每一行元素的每個可能的組合。例如,對於數組{{1,2,3},{4,5,6}},我需要輸出{{1,4},{1,5},{1,6},{2,4},{2,5},{2,6},{3,4},{3,5},{3,6}}矩陣元素組合


我覺得應該有A M循環來解決這個問題。對於上面的示例,我寫的代碼:

 int[,] array = new int[,] {{1, 2, 3}, {4, 5, 6}}; 

     for (var i = 0; i < 3; i++) 
     { 
      for (var j = 0; j < 3; j++) 
      { 
       Console.WriteLine($"{{{array[0, i]},{array[1, j]}}}"); 
      } 
     } 

隨着米變化,for循環的數量也改變。但是當我編寫代碼時,m是未知的。我該如何解決它?

+0

請刪除算法標籤,並添加相關的語言標記 –

回答

0

維護活動組合列表c。初始化c是數組的第一行。然後迭代每一行,並更新c。基本上,你會增加每個行的每個項目的當前組合。這裏有一些僞代碼:

c = array[0]; //read: the first row of the array 
for(var i = 1; i < m; ++i) { //iterate all rows 
    var c_modified = []; 
    for(var j = 0; j < n; ++j) { //iterate all row entries 
     for(var k = 0; k < c.length; ++k) { //iterate all entries of c 
      add c[k].array[i, j] to c_modified; // . represents concatenation 
     } 
    } 
    c = c_modified; 
} 
0

這種元素組合(n^m集合)被稱爲笛卡兒積。在某些語言庫中有其即時可用的功能

我相信最簡單的代碼是遞歸的。

type 
    TArr2D = TArray<TArray<Integer>>; 

procedure CartesianProduct(const A: TArr2D; Line: Integer; Reslt: TArray<Integer>); 
var 
    i: integer; 
begin 
    if Line > High(A) then 
    Memo1.Lines.Add(ArrayToString(Reslt)) // output m-element set 
    else 
    for i in A[Line] do 
     CartesianProduct(A, Line + 1, Reslt + [i]); // include element in set 
end; 

var 
    A: TArr2D; 
    n, m, i, j: Integer; 
begin 
    m := 3; 
    n := 3; 
    SetLength(A, m, n); 
    for j := 0 to m - 1 do 
    for i := 0 to n - 1 do 
     A[j, i] := j * n + i; 
    //0 1 2 
    //3 4 5 
    //6 7 8 

    CartesianProduct(A, 0, []); 

0 3 6 
0 3 7 
0 3 8 
0 4 6 
0 4 7 
0 4 8 
0 5 6 
0 5 7 
0 5 8 
1 3 6 
1 3 7 
1 3 8 
1 4 6 
1 4 7 
1 4 8 
1 5 6 
1 5 7 
1 5 8 
2 3 6 
2 3 7 
2 3 8 
2 4 6 
2 4 7 
2 4 8 
2 5 6 
2 5 7 
2 5 8