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

Posted

技术标签:

【中文标题】二维数组中长度为 8 的所有可能组合【英文标题】:All possible combinations of length 8 in a 2d array 【发布时间】:2011-05-30 03:11:48 【问题描述】:

我一直在尝试以组合方式解决问题。我有一个 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.

限制是您必须从任何点移动到您的邻居,您必须从矩阵中的每个位置开始,即每一行,col。您可以一次移动一步,即右、左、上、下和两个对角线位置。检查 if 条件。 IE 如果您在 (0,0) 中,您可以移动到 (1,0) 或 (1,1) 或 (0,1) ,即三个邻居。 如果您在 (2,2) 中,您可以搬到八个邻居。 等等……

【问题讨论】:

你怎么称呼这个,你有样本输出吗?当您说长度 8 时,是否有任何限制(方向)适用 - 或者它是来自任何位置的任何方向? 限制是你必须从任何一点移动到你的邻居,你必须从矩阵中的每个位置开始,即每一行,col。您可以一次移动一步,即右、左、上、下和两个对角线位置。检查 if 条件。 【参考方案1】:

为了消除重复,您可以将 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

【讨论】:

我不想在计算后消除重复项,而是在计算它们之前消除它们。我这种记忆可以完成这项工作,但速度仍然较慢.在递归中节省 7 个步骤。 :) @CodeJunki 你不能防止重复;您需要先创建一个,然后才能知道它是重复的 :) 再次阅读第二段 - 优化是首先创建短序列,然后通过预先设置所有可能的方式到达单元格来增长它们(即有 3 种方法可以到达角落牢房,8到“中间”牢房等)。这是一个经典的动态规划解决方案。【参考方案2】:

有很多方法可以做到这一点。经历每一个组合是一个完全合理的第一种方法。这一切都取决于您的要求。如果您的矩阵很小,并且此操作对时间不敏感,那么就没有问题。

我并不是真正的算法专家,但我敢肯定有一些非常聪明的方法可以做到这一点,有人会在我之后发布。

另外,在 Java 中在使用 CamelCase 时,方法名称应该以小写字符开头。

【讨论】:

这取决于你想要什么。根据您对输出的了解,您可以进行一些优化。【参考方案3】:

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 行,依此类推。这是你所期待的吗?

【讨论】:

我认为他想要 8 位数字序列。【参考方案4】:

你可以把你的矩阵想象成一维数组——不管在这里(一一“放置”行)。对于一维数组,您可以编写如下函数(假设您应该打印组合)

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)。

【讨论】:

以上是关于二维数组中长度为 8 的所有可能组合的主要内容,如果未能解决你的问题,请参考以下文章

java二维数组

创建二维数组(一维长度3,二维长度6),值为一维数组和二维数组索引值的积

创建二维数组(一维长度3,二维长度6),值为一维数组和二维数组索引值的积,

用 0 和 1 填充的 numpy 二维数组的所有组合

获取二维数组的大小[重复]

二维数组中的查找