简体   繁体   English

二维数组中长度8的所有可能组合

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

I've been trying to solve a problem in combinations. 我一直在尝试解决组合问题。 I have a matrix 6X6 i'm trying to find all combinations of length 8 in the matrix. 我有一个6X6矩阵,我试图在矩阵中找到长度8的所有组合。

I have to move from neighbor to neighbor form each row,column position and i wrote a recursive program which generates the combination but the problem is it generates a lot of duplicates as well and hence is inefficient. 我必须在每一行,每一列的位置上从一个邻居移到另一个邻居,并且编写了一个递归程序来生成组合,但是问题是它也会生成很多重复项,因此效率很低。 I would like to know how could i eliminate calculating duplicates and save time. 我想知道如何消除重复计算并节省时间。

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);
   }

I was also thinking of writing a dynamic program basically recursion with memorization. 我也在考虑编写一个动态程序,基本上是通过记忆来递归的。 Is it a better choice?? 这是一个更好的选择吗? if yes than I'm not clear how to implement it in recursion. 如果是,那么我不清楚如何在递归中实现它。 Have i really hit a dead end with approach??? 我真的有办法走到尽头吗???

Thankyou 谢谢

Edit Eg result 12121212,12121218,12121219,12121211,12121213. 编辑例如结果12121212、12121218、12121219、12121211、12121213。

the restrictions are that you have to move to your neighbor from any point, you have to start for each position in the matrix ie each row,col. 限制是您必须从任何点移至邻居,必须从矩阵中的每个位置(即每一行,列)开始。 you can move one step at a time, ie right, left, up, down and the both diagonal positions. 您可以一次移动一步,即向右,向左,向上,向下和两个对角线位置。 Check the if conditions. 检查是否满足条件。 ie if your in (0,0) you can move to either (1,0) or (1,1) or (0,1) ie three neighbors. 例如,如果您输入的是(0,0),则可以移动到(1,0)或(1,1)或(0,1),即三个邻居。 if your in (2,2) you can move to eight neighbors. 如果您的收入(2,2),您可以搬到八个邻居。
so on... 等等...

To eliminate duplicates you can covert 8 digit sequences into 8-digit integers and put them in a hashtable. 要消除重复,您可以将8位数字序列转换为8位整数,并将其放入哈希表中。

Memoization might be a good idea. 记忆化可能是一个好主意。 You can memoize for each cell in the matrix all possible combinations of length 2-7 that can be achieved from it. 您可以为矩阵中的每个单元记忆所有可以从中获得的长度2-7的可能组合。 Going backwards: first generate for each cell all sequences of 2 digits. 向后:首先为每个单元格生成所有2位数字的序列。 Then based on that of 3 digits etc. 然后根据3位数字等

UPDATE: code in Python 更新: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

There are LOTS of ways to do this. 有很多方法可以做到这一点。 Going through every combination is a perfectly reasonable first approach. 进行每种组合都是一种完全合理的第一种方法。 It all depends on your requirements. 这完全取决于您的要求。 If your matrix is small, and this operation isn't time sensitive, then there's no problem. 如果矩阵很小,并且此操作对时间不敏感,那么就没有问题。

I'm not really an algorithms guy, but I'm sure there are really clever ways of doing this that someone will post after me. 我不是一个真正的算法专家,但是我敢肯定,有人会在我后面发布一些非常聪明的方法。

Also, in Java when using CamelCase, method names should start with a lowercase character. 另外, 在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}, }

By length you mean summation of combination of matrix elements resulting 8. 长度是指矩阵元素的组合之和,结果为8。
ie, elements to sum up 8 with in row itself and with the other row elements. 也就是说,要与行本身以及与其他行元素相加的元素8。
From row 1 = { {2,6}, {3,5}, } and now row 1 elements with row 2 and so on. 从第1行= {{2,6},{3,5},}开始,到第1行元素再加上第2行,依此类推。 Is that what you are expecting ? 那是您所期望的吗?

You can think about your matrix like it is one-dimension array - no matter here ("place" the rows one by one). 您可以将矩阵想像成一​​维数组-无论在这里(将行一一“放置”)。 For one-dimension array you can write a function like (assuming you should print the combinations) 对于一维数组,您可以编写类似的函数(假设您应该打印组合)

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

It should skip some elements from a[i] to a[i + k] (for all possible k), print a[k] and make a recursive call f(i + k + 1, n - 1). 它应该从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