jcpython2 发表于 2023-1-16 16:54:01

按Z顺序输出字母



题目要求图左的n*n字符矩阵转换到图右的矩阵

我现在的思路是把做图按顺序提取出来先

思路提取坐标有以下情况

极限行
首行 奇   首行 偶
尾行 奇   尾行 偶

极限列
基 首列    偶 首列
基 尾列   偶 尾列


奇奇 右上
奇偶 左下
偶奇 左下
偶偶 右上


我分别定义了函数,但程序一直没有移动坐标提取 得出的一直是首位字母T,看一个下午没查到出错处

请高手可以的话纠正以下我这段代码,或者提供其他解题思路

class mov: #移动操作 右 下 右上 左下
    '移动操作'
    def right(x,y):
      return x,y+1
    def down(x,y):
      return x+1,y
    def rup(x,y):
      return x-1,y+1
    def ldown(x,y):
      return x+1,y-1

#边缘判断+处理
def limit(x,y):
    '极限行'
    #0 0判断
    if x==0 and y ==0:
      return x,y+1
    if x != 0 or x != (n-1) or y != 0 or y != (n-1):
      print(x,y,'false')
      return False
   
   

    if x == 0 or x == (n-1):
      if x == 0 and y%2 !=0:#首行 奇列
            return mov.right(x,y)
      elif x ==0 and y%2 ==0: #首行 偶列
            return mov.ldown(x,y)
      elif x == (n-1) and y%2 != 0: #尾行 奇列 右上
            return mov.rup(x,y)
      elif x ==(n-1) and y%2 ==0: #尾行 偶列 右
            return mov.right(x,y)

    #极限列
    elif y == 0 or y == (n-1):
      if y ==0 and x %2 != 0:#首列 奇行 右上
            return mov.rup(x,y)
      elif y == (n-1) and x %2 ==0:#首列 偶行 下
            return mov.down(x,y)
      elif y == (n-1) and x%2 != 0:#尾列 基行 下
            return mov.down(x,y)
      elif y== (n-1) and x %2 == 0:#尾列 偶行 左下
            return mov.ldown(x,y)
    else:
      return False

#中部定位
def ways(x,y):
    if (x %2 !=0 and y %2 != 0) or (x%2==0 and y%2==0) :#奇行奇列偶行偶列
      return mov.rup(x,y)
    elif (x%2 != 0 and y%2 ==0) or (x%2==0 and y%2 !=0): #奇行偶列 或者 偶行奇列
      return mov.ldown(x,y)


lst = [['T', 'H', 'S', 'A', 'D'], ['I', 'I', 'V', 'O', 'P'], ['S', 'E', 'O', 'O', 'H'], ['R', 'G', 'E', 'T', 'I'], ['Y', 'M', 'I', 'N', 'K']]
n= 5
row =0
col = 0




for i in range(25):
    if limit(row,col):
      row,col == limit(row,col),limit(row,col)
      #print('当前rc',row,col)
      print(lst,end="")
    else:
      row,col == ways(row,col),ways(row,col)
      print(lst,end="")

isdkz 发表于 2023-1-16 23:15:58

本帖最后由 isdkz 于 2023-1-17 18:23 编辑

我的想法是创建一个指针矩阵,这个矩阵可以像文件读写一样读出数据和写入数据时指针都会跟着移动,

然后我创建了两种不同的指针,它们的移动规则分别对应上面两种矩阵的箭头的规则,

指针里面有x坐标,y坐标,方向三种属性,有一个 move 方法,move 方法先判断出方向,

然后根据相应的方向来改变坐标

参考代码:
class Pointer:
    def __init__(self, x=0, y=0, orient=0):
      self.x = x
      self.y = y
      self.orient = orient
   
    def move(self):
      pass

class PointerA(Pointer):
    def __init__(self, x=0, y=0, orient=0):
      self.orient_lst =
      self.status = 1
      self.count = 0
      super().__init__(x, y, orient)

    def move(self, pm):
      # 根据方向来控制行索引、列索引的改变
      # 如果方向为向右走:
      if self.orient == 0:
            self.x += 1
      # 如果方向为向下走:
      elif self.orient == 2:
            self.y += 1
      # 如果方向为向左下走:
      elif self.orient == 1:
            self.x -= 1
            self.y += 1
      # 如果方向为向右上走:
      elif self.orient == 3:
            self.y -= 1
            self.x += 1
      # 这个因为到对角线那里的时候规则发生反转,所以改变了状态
      if ((self.x == 0 and self.y == pm.n - 1 and self.orient == 1) or
            (self.y == 0 and self.x == pm.n - 1 and self.orient == 3)):
            self.status = -1
      # 到达边缘改变移动方向
      if self.x == 0 or self.x == pm.n - 1 or self.y == 0 or self.y == pm.n - 1:
            self.count += self.status * 1
      self.orient = self.orient_lst

class PointerB(Pointer):
    def move(self, pm):
      # orient(0向右,1向下,2向左,3向上)
      if self.x + self.y == pm.n - 1:
            # x > y, 位于右上角
            if self.x > self.y:
                self.orient = 1
            # 位于左下角
            else:
                self.orient = 3
      elif (self.x == self.y) and (self.x >= pm.n / 2):
            self.orient = 2
      elif (self.x == self.y - 1) and (self.y <= pm.n / 2):
            self.orient = 0
      # 根据方向来控制行索引、列索引的改变
      # 如果方向为向右走:
      if self.orient == 0:
            self.x += 1
      # 如果方向为向下走:
      elif self.orient == 1:
            self.y += 1
      # 如果方向为向左走:
      elif self.orient == 2:
            self.x -= 1
      # 如果方向为向上走:
      elif self.orient == 3:
            self.y -= 1
            
class PointerMatrix:
    def __init__(self, data, p):
      self.n = len(data)
      if not all(len(i) == self.n for i in data):
            raise ValueError(f"{data}不是一个n * n 的矩阵")
      self.data = data
      self.p = p
   
    def read(self):
      value = self.data
      self.p.move(self)
      return value
   
    def write(self, value):
      self.data = value
      self.p.move(self)
   
    def __str__(self):
      return '\n' + '\n'.join(
            ''.join(map(lambda x: f'{x:3}' , i))
            for i in self.data
      )

lst_a = [
    ['T', 'H', 'S', 'A', 'D'],
    ['I', 'I', 'V', 'O', 'P'],
    ['S', 'E', 'O', 'O', 'H'],
    ['R', 'G', 'E', 'T', 'I'],
    ['Y', 'M', 'I', 'N', 'K']
]
pa = PointerA()
pma = PointerMatrix(lst_a, pa)
n = pma.n
lst_b = [[''] * n for i in range(n)]# 初始化一个n*n的矩阵
pb = PointerB()
pmb = PointerMatrix(lst_b, pb)

for _ in range(n**2):
    pmb.write(pma.read())

print('原始矩阵:', pma)
print()
print('转换后的矩阵:', pmb)

isdkz 发表于 2023-1-16 23:18:19

至于你的代码是什么问题我有空再帮你看看,我暂时看不大懂你的代码

jcpython2 发表于 2023-1-16 23:52:36

isdkz 发表于 2023-1-16 23:18
至于你的代码是什么问题我有空再帮你看看,我暂时看不大懂你的代码

我的代码思路是 先判断是否在矩阵边缘,如果是就按照指定规则移动def limit(x,y):

如果不是在矩阵边缘,那么他的移动方式就只有两种 右上和左下mov.rup(x,y) mov.ldown(x,y)

然后循环N*N 次每次return更新新的坐标row col代入循环

按照你的说法,我的思路其实是相似的

你的代码class写得比较长,我得先消化下,那个self总让我头晕

jcpython2 发表于 2023-1-16 23:54:06

isdkz 发表于 2023-1-16 23:18
至于你的代码是什么问题我有空再帮你看看,我暂时看不大懂你的代码

高手你的代码直接解题了,然而我还在第一步先从第一个图提取一个列表出来而已,后面那个图的转换法我还没去想{:10_282:}

isdkz 发表于 2023-1-17 12:47:48

本帖最后由 isdkz 于 2023-1-17 12:50 编辑

jcpython2 发表于 2023-1-16 23:52
我的代码思路是 先判断是否在矩阵边缘,如果是就按照指定规则移动def limit(x,y):

如果不是在矩阵边缘, ...

我发现一个问题,你这里把赋值符号=写成关系运算符==了,还有

其实可以直接这样给两个变量赋值的,没必要写那么长: row,col = limit(row,col)

for i in range(25):
    if limit(row,col):
      row,col == limit(row,col),limit(row,col)
      #print('当前rc',row,col)
      print(lst,end="")
    else:
      row,col == ways(row,col),ways(row,col)
      print(lst,end="")
页: [1]
查看完整版本: 按Z顺序输出字母