簡體   English   中英

二維數組中長度8的所有可能組合

[英]All possible combinations of length 8 in a 2d array

我一直在嘗試解決組合問題。 我有一個6X6矩陣,我試圖在矩陣中找到長度8的所有組合。

我必須在每一行,每一列的位置上從一個鄰居移到另一個鄰居,並且編寫了一個遞歸程序來生成組合,但是問題是它也會生成很多重復項,因此效率很低。 我想知道如何消除重復計算並節省時間。

int a={{1,2,3,4,5,6},
   {8,9,1,2,3,4},
   {5,6,7,8,9,1},
   {2,3,4,5,6,7},
   {8,9,1,2,3,4},
   {5,6,7,8,9,1},
  }

 void genSeq(int row,int col,int length,int combi)
 {
    if(length==8)
    {
      printf("%d\n",combi);
      return;
    }
    combi = (combi * 10) + a[row][col];
    if((row-1)>=0)

    genSeq(row-1,col,length+1,combi);

if((col-1)>=0)

    genSeq(row,col-1,length+1,combi);

if((row+1)<6)

    genSeq(row+1,col,length+1,combi);

if((col+1)<6)

    genSeq(row,col+1,length+1,combi);

if((row+1)<6&&(col+1)<6)

    genSeq(row+1,col+1,length+1,combi);

if((row-1)>=0&&(col+1)<6)

    genSeq(row-1,col+1,length+1,combi);

if((row+1)<6&&(row-1)>=0)

    genSeq(row+1,col-1,length+1,combi);

if((row-1)>=0&&(col-1)>=0)

    genSeq(row-1,col-1,length+1,combi);
   }

我也在考慮編寫一個動態程序,基本上是通過記憶來遞歸的。 這是一個更好的選擇嗎? 如果是,那么我不清楚如何在遞歸中實現它。 我真的有辦法走到盡頭嗎???

謝謝

編輯例如結果12121212、12121218、12121219、12121211、12121213。

限制是您必須從任何點移至鄰居,必須從矩陣中的每個位置(即每一行,列)開始。 您可以一次移動一步,即向右,向左,向上,向下和兩個對角線位置。 檢查是否滿足條件。 例如,如果您輸入的是(0,0),則可以移動到(1,0)或(1,1)或(0,1),即三個鄰居。 如果您的收入(2,2),您可以搬到八個鄰居。
等等...

要消除重復,您可以將8位數字序列轉換為8位整數,並將其放入哈希表中。

記憶化可能是一個好主意。 您可以為矩陣中的每個單元記憶所有可以從中獲得的長度2-7的可能組合。 向后:首先為每個單元格生成所有2位數字的序列。 然后根據3位數字等

更新:Python中的代碼

# original matrix
lst = [
   [1,2,3,4,5,6],
   [8,9,1,2,3,4],
   [5,6,7,8,9,1],
   [2,3,4,5,6,7],
   [8,9,1,2,3,4],
   [5,6,7,8,9,1]]

# working matrtix; wrk[i][j] contains a set of all possible paths of length k which can end in lst[i][j]
wrk = [[set() for i in range(6)] for j in range(6)]

# for the first (0rh) iteration initialize with single step paths
for i in range(0, 6):
    for j in range(0, 6):
        wrk[i][j].add(lst[i][j])

# run iterations 1 through 7
for k in range(1,8):
    # create new emtpy wrk matrix for the next iteration
    nw = [[set() for i in range(6)] for j in range(6)]

    for i in range(0, 6):
        for j in range(0, 6):
            # the next gen. wrk[i][j] is going to be based on the current wrk paths of its neighbors
            ns = set()
            if i > 0:
                for p in wrk[i-1][j]:
                    ns.add(10**k * lst[i][j] + p)
            if i < 5:
                for p in wrk[i+1][j]:
                    ns.add(10**k * lst[i][j] + p)
            if j > 0:
                for p in wrk[i][j-1]:
                    ns.add(10**k * lst[i][j] + p)
            if j < 5:
                for p in wrk[i][j+1]:
                    ns.add(10**k * lst[i][j] + p)

            nw[i][j] = ns
    wrk = nw

# now build final set to eliminate duplicates
result = set()

for i in range(0, 6):
    for j in range(0, 6):
        result |= wrk[i][j]

print len(result)
print result

有很多方法可以做到這一點。 進行每種組合都是一種完全合理的第一種方法。 這完全取決於您的要求。 如果矩陣很小,並且此操作對時間不敏感,那么就沒有問題。

我不是一個真正的算法專家,但是我敢肯定,有人會在我后面發布一些非常聰明的方法。

另外, 在Java中 使用CamelCase時,方法名稱應以小寫字母開頭。

int a={{1,2,3,4,5,6}, {8,9,1,2,3,4}, {5,6,7,8,9,1}, {2,3,4,5,6,7}, {8,9,1,2,3,4}, {5,6,7,8,9,1}, }

長度是指矩陣元素的組合之和,結果為8。
也就是說,要與行本身以及與其他行元素相加的元素8。
從第1行= {{2,6},{3,5},}開始,到第1行元素再加上第2行,依此類推。 那是您所期望的嗎?

您可以將矩陣想像成一​​維數組-無論在這里(將行一一“放置”)。 對於一維數組,您可以編寫類似的函數(假設您應該打印組合)

f(i, n) prints all combinations of length n using elements a[i] ... a[last].

它應該從a [i]到a [i + k]跳過某些元素(對於所有可能的k),打印a [k]並進行遞歸調用f(i + k + 1,n-1)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM