【问题标题】:Pattern Programs - Matrix Alphabet Pattern模式程序 - 矩阵字母模式
【发布时间】:2021-02-11 18:06:16
【问题描述】:

尝试制作矩阵字母图案。所需的输出应如下所示:

DDDDDDD
DCCCCCD
DCBBBCD
DCBABCD
DCBBBCD
DCCCCCD
DDDDDDD

我找到了矩阵数字模式的解决方案:

输入:4

N = int(input('Enter N value:'))
k = (2 * N) - 1
low = 0
high = k - 1
value = N
matrix = [[0 for i in range(k)] for j in range(k)]
for i in range(N):
    for j in range(low, high + 1):
        matrix[i][j] = value
    for j in range(low + 1, high + 1):
        matrix[j][i] = value
    for j in range(low + 1, high + 1):
        matrix[high][j] = value
    for j in range(low + 1, high):
        matrix[j][high] = value

    low = low + 1
    high = high - 1
    value = value - 1

for i in range(k):
    for j in range(k):
        print(matrix[i][j], end =' ')
    print()

输出:

4 4 4 4 4 4 4 
4 3 3 3 3 3 4 
4 3 2 2 2 3 4 
4 3 2 1 2 3 4 
4 3 2 2 2 3 4 
4 3 3 3 3 3 4 
4 4 4 4 4 4 4 

不确定这个矩阵数字模式代码是否是最平滑的解决方案。

【问题讨论】:

  • 你需要将数字转换成字母吗?
  • 是的,我不知道该怎么做。
  • 这是我解决方案的最后一步。 chr(64+matrix[i][j]) 在您的打印循环中为您提供您愿意使用的 ascii 字符
  • 嗨,您现在已经有了答案,您可以考虑accepting an answer 来奖励给您最有帮助的评论。

标签: python


【解决方案1】:

看起来你只需要从数字传递到大写字母,你也不需要额外的变量lowvalue,只需使用现有的Ni

from string import ascii_uppercase # simple string of all alphabet

N = int(input('Enter N value:'))
k = (2 * N) - 1
high = k - 1
matrix = [[0 for _ in range(k)] for _ in range(k)]

for i in range(N):
    for j in range(i, high + 1):
        matrix[i][j] = N - i
    for j in range(i + 1, high + 1):
        matrix[j][i] = N - i
    for j in range(i + 1, high + 1):
        matrix[high][j] = N - i
    for j in range(i + 1, high):
        matrix[j][high] = N - i

    high = high - 1
    
for i in range(k):
    for j in range(k):
        print(ascii_uppercase[matrix[i][j] - 1], end='')
    print()

【讨论】:

    【解决方案2】:

    将其视为距矩阵中心的距离并带有偏移量。

    [[int(max(abs((n-1)/2-i),abs((n-1)/2-j)))+1 for i in range(n)] for j in range(n)]
    
    [[4, 4, 4, 4, 4, 4, 4],
     [4, 3, 3, 3, 3, 3, 4],
     [4, 3, 2, 2, 2, 3, 4],
     [4, 3, 2, 1, 2, 3, 4],
     [4, 3, 2, 2, 2, 3, 4],
     [4, 3, 3, 3, 3, 3, 4],
     [4, 4, 4, 4, 4, 4, 4]]
    

    这里n是一个奇数,矩阵的中心是(n-1)/2。由于您希望在中心添加一个“1”作为偏移量,因此除法将数字转换为浮点格式,因此 int() 可以很好地格式化。列表推导可以转换为嵌套循环,但这种方式看起来很好,因为消除了矩阵初始化步骤。

    该距离称为切比雪夫距离(或棋盘距离)。

    要将矩阵转换为字符串数组,请将数字转换为相应的字符并连接行。此时可读性失败

    [''.join([chr(ord('A')+int(max(abs((n-1)/2-i),abs((n-1)/2-j)))) for i in range(n)]) for j in range(n)]
    
    ['DDDDDDD', 'DCCCCCD', 'DCBBBCD', 'DCBABCD', 'DCBBBCD', 'DCCCCCD', 'DDDDDDD']
    

    使用函数!

    def chebDist(i,j,n):
        return int(max(abs((n-1)/2-i),abs((n-1)/2-j)))
    
    def toChar(d):
        return chr(ord('A')+d-1) 
    
    [''.join([toChar(chebDist(i,j,n)+1) for i in range(n)]) for j in range(n)]
    

    会给你

    ['DDDDDDD', 'DCCCCCD', 'DCBBBCD', 'DCBABCD', 'DCBBBCD', 'DCCCCCD', 'DDDDDDD']
    

    或者这种格式

    print('\n'.join([''.join([toChar(chebDist(i,j,n)+1) for i in range(n)]) for j in range(n)]))
    
    DDDDDDD
    DCCCCCD
    DCBBBCD
    DCBABCD
    DCBBBCD
    DCCCCCD
    DDDDDDD
    

    可读且具有可重复使用的功能!

    您也许可以通过分离转换使其更具可读性,由于中间值而权衡是效率

    首先创建数值矩阵

    m=[[chebDist(i,j,n)+1 for i in range(n)] for j in range(n)]
    

    转换为字符映射

    c=[[toChar(e) for e in row] for row in m]
    

    转换为字符串表示并打印。

    print('\n'.join([''.join(row) for row in c]))
    

    更新

    最后,全部封装成 4 个通用函数和 2 行代码。

    def chebDist(i,j,n):
        return int(max(abs((n-1)/2-i),abs((n-1)/2-j)))
    
    def toChar(d):
        return chr(ord('A')+d-1) 
    
    def map2(f,m):
        return [[f(e) for e in row] for row in m]
    
    def toString(a):
        return '\n'.join(map(''.join,a))
    
    
    m=[[chebDist(i,j,n)+1 for i in range(n)] for j in range(n)]
    print(toString(map2(toChar,m)))
    

    【讨论】:

    • 像另一个答案一样,单行很少有可读性,当它不是一个简单的列表理解时
    • 感谢您的帮助!
    【解决方案3】:

    我们可以在单个输入行和单个输出行中解决所有问题:

    N = int(input('Enter N value:'))
    print('\n'.join([''.join([chr(64+max(max(N-i,N-j),max(i-N+2,j-N+2))) for i in range(2*N-1)]) for j in range(2*N-1)]))
    

    说明: 我们将在这个2*N-1x2*N-1 网格中工作,现在使用零:

    [[0 for i in range(2*N-1)] for j in range(2*N-1)]
    

    然后,我们想要格式化,所以我们将事物转换为字符串并加入它们:

    print('\n'.join([''.join([str(0) for i in range(2*N-1)]) for j in range(2*N-1)]))
    

    好的,我们有零,但我们想要你的数字矩阵,所以我们将这个公式应用于具有ij 索引max(max(N-i,N-j),max(i-N+2,j-N+2)) 的矩阵:

    print('\n'.join([''.join([str(max(max(N-i,N-j),max(i-N+2,j-N+2))) for i in range(2*N-1)]) for j in range(2*N-1)]))
    

    现在我们有了数字矩阵,让我们应用这个转换: chr(64+k) => 大写字母,从零开始,因为 'A' 是 ascii 代码 64,'B' 是 ascii代码65,等等……

    print('\n'.join([''.join([chr(64+max(max(N-i,N-j),max(i-N+2,j-N+2))) for i in range(2*N-1)]) for j in range(2*N-1)]))
    

    我们有它。

    【讨论】:

    • 为什么我仅仅因为提出不同的解决方案而被否决?我真的很喜欢没有 fors 的代码,这对我来说似乎是 Pythonic。
    • 我没有投反对票,但我可以猜到:投反对票可能是“无效”答案,并且有不同的标准,这里的 OP 似乎仍在学习,您的解决方案不适用到了他的水平,就算是写代码多的我,也绝对不会写出这么难读的代码
    • 我投了反对票,因为像这样复杂的单行代码是非常糟糕的做法,而且 OP 显然是初学者。我注意到您在编辑中解释了您的答案,但我的观点仍然成立。不管你怎么想,一个凌乱的单线显然不是 Pythonic。
    • 感谢您提供不同类型的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多