如何从二维字符数组中将对角线提取为字符串?

时间:2015-08-01 17:18:47

标签: python multidimensional-array

我一直试图以编程方式解决下面的单词拼图作为我自己的练习:

puzzle = [
    ['t', 'r', 'o', 'l', 'l'],
    ['u', 'u', 'a', 'a', 'y'],
    ['n', 'r', 'r', 'e', 'q'],
    ['a', 'o', 'h', 'd', 'q']]
words = ["troll", "tuna", "nut", "oral", "turd", "deal", "rut", "hey", "ear"]

但是我需要一些帮助来完成练习。这是我到目前为止所做的:

我将行和列转换为单个字符串并将它们放入列表中:

a = []

#Rows
for x in puzzle:
    a.append(''.join(x))
    a.append(''.join(x)[::-1])  #Append reversed string.

#Columns
for i in range(len(puzzle[0])):
    s = ""
    for j in range(len(puzzle)):
        s += puzzle[j][i]
    a.append(s)
    a.append(''.join(s)[::-1])  #Append reversed string.

所以现在我可以找到水平或垂直拼写的任何单词。正如您可能已经猜到的那样,下一步是通过对角线并将它们放入列表中,但是无法弄清楚这样做的逻辑。任何人都可以帮我这个吗?

2 个答案:

答案 0 :(得分:1)

这样想:

  1. 在行中找到的字词是序列puzzle[a][b+i]

  2. 列中的字词是序列puzzle[a+i][b]

  3. 在对角线上找到的字词是序列puzzle[a+i][b+i]puzzle[a+i][b-i]

  4. 表示i=0,...,n,每个整数a,b,n,以便生成的所有索引都在表中。您可以向前和向后检查序列。通过在a,b,n上设置约束来实现其他约束,例如仅考虑完整行。特别是,我解释它的方式是你想要在每种情况下尽可能长的字符串;在这种情况下,您只需将n设置为每个a,b的最大可能值。

    你已经有1.和2.下来了。我建议您从列的解决方案开始,并尝试将其应用于3.中描述的序列。

答案 1 :(得分:0)

首先,查看嵌套列表中所有元素的索引:

(0,0) (0,1) (0,2) (0,3) (0,4)
(1,0) (1,1) (1,2) (1,3) (1,4)
(2,0) (2,1) (2,2) (2,3) (2,4)
(3,0) (3,1) (3,2) (3,3) (3,4)
(4,0) (4,1) (4,2) (4,3) (4,4)

从这里你可以写下对角线上半部分的索引,以了解模式:

(0,4)
(0,3), (1,4)
(0,2), (1,3), (2,4)
(0,1), (1,2), (2,3), (3,4)
(0,0), (1,1), (2,2), (3,3), (4,4)

我们如何生成这些配对列表?首先,让我们看看外部循环。外部循环将跨越第一个子列表的顶部,即(0,j)对,其中j从最后一个索引开始倒计时:

for j in range(len(puzzle), -1, -1):
    print((0, j))

#output:
(0, 4)
(0, 3)
(0, 2)
(0, 1)
(0, 0)

然后我们需要让内循环在每一步中向下和向右移动,并且永远不要超过列表的末尾:

for j in range(len(puzzle), -1, -1):
    for i in range(len(puzzle)):
        j += 1
        if j > len(puzzle):
             break
        print((i,j))
    print("")

输出:

(0, 4)

(0, 3)
(1, 4)

(0, 2)
(1, 3)
(2, 4)

(0, 1)
(1, 2)
(2, 3)
(3, 4)

如果你让外环从N..-1开始,那么你也可以得到穿过中心的对角线。之后,使用类似的逻辑来获得对角线的下半部分。

要使对角线朝另一个方向移动,你可以再次使用相同类型的逻辑(通过查看你想要的索引,编写外部循环,然后编写内部循环),或者你可以反转每个子列表(将其视为镜像图像,或在垂直线上反射二维数组!当您这样做时,所有对角线都将以“相反”方向穿过元素。)