鱼C论坛

 找回密码
 立即注册
查看: 2437|回复: 5

[已解决]按Z顺序输出字母

[复制链接]
发表于 2023-1-16 16:54:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1547514156.png

题目要求图左的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)[0],limit(row,col)[1]
        #print('当前rc',row,col)
        print(lst[row][col],end="")
    else:
        row,col == ways(row,col)[0],ways(row,col)[1]
        print(lst[row][col],end="")
最佳答案
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 = [0, 1, 2, 3]
        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[self.count % 4]

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.y][self.p.x]
        self.p.move(self)
        return value
    
    def write(self, value):
        self.data[self.p.y][self.p.x] = 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)

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 = [0, 1, 2, 3]
        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[self.count % 4]

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.y][self.p.x]
        self.p.move(self)
        return value
    
    def write(self, value):
        self.data[self.p.y][self.p.x] = 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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-16 23:18:19 | 显示全部楼层
至于你的代码是什么问题我有空再帮你看看,我暂时看不大懂你的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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总让我头晕
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-16 23:54:06 | 显示全部楼层
isdkz 发表于 2023-1-16 23:18
至于你的代码是什么问题我有空再帮你看看,我暂时看不大懂你的代码

高手你的代码直接解题了,然而我还在第一步先从第一个图提取一个列表出来而已,后面那个图的转换法我还没去想
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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)[0],limit(row,col)[1]
        #print('当前rc',row,col)
        print(lst[row][col],end="")
    else:
        row,col == ways(row,col)[0],ways(row,col)[1]
        print(lst[row][col],end="")
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-24 21:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表