鱼C论坛

 找回密码
 立即注册
查看: 2658|回复: 8

[已解决]求个大佬分析详细点,让我一看就能理解那种

[复制链接]
发表于 2022-8-20 16:06:54 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 wangyanren 于 2022-8-20 19:42 编辑

请按照顺时针螺旋顺序输出矩阵中的所有元素,输出结果:[1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]

atrix = [[1, 2, 3, 4],
          [5, 6, 7, 8],
          [9, 10, 11, 12]]

rows = len(matrix)
cols = len(matrix[0])

left = 0
right = cols - 1
top = 0
bottom = rows - 1

result = []

while left <= right and top <= bottom:
    for col in range(left,right+1):
        result.append(matrix[top][col])

    for row in range(top+1,bottom+1):
        result.append(matrix[row][right])

    if left < right and top < bottom:
        for col in range(right-1,left,-1):
            result.append(matrix[bottom][col])
        for row in range(bottom,top,-1):
            result.append(matrix[row][left])

   

    left = left + 1
    right = right - 1
    top = top + 1
    bottom = bottom - 1

print(result)
最佳答案
2022-8-21 14:58:06
我的思路是这样:
往右往下往左往上走一圈为一个rounds
用for循环设置rounds参数限制位置
用while循环分别走四个方向并打印(也可以将元素输出到列表啊啥的)

matrix = [[1,2,3,4,5],
          [6,7,8,9,0],
          [11,12,13,14,15],
          [16,17,18,19,20],
          [21,22,23,24,25],
          [26,27,28,29,30]]
# 获取列表长度6
rows = len(matrix)
# 获取列表宽度5
cols = len(matrix[0])

for rounds in range(3):
    # 将位置参数初始化为第rounds圈,第一位置为[rounds][rounds]
    left = top = rounds
    # 右边界限为列表宽度-圈数-1
    right = cols - rounds - 1
    # 底部界限为列表长度-圈数-1
    bottom = rows - rounds - 1
    # 判定是否还有继续循环的必要,left>=right且top>=bottom则跳出
    if left >= right and top >= bottom:
        break
    # 顶部为第一序列
    while left <= right:
        # 输出第top行第left列
        print(matrix[top][left])
        # 位置往右移动
        left += 1
    # 右边为第二序列
    while top < bottom:
        # 位置往下移动
        top += 1
        # 输出top行right列
        print(matrix[top][right])
    while right > rounds:
        # 位置往左移动
        right -= 1
        # 输出bottom行right列
        print(matrix[bottom][right])
    while bottom > rounds+1:
        # 位置往上移动
        bottom-=1
        # 输出bottom行rounds列
        print(matrix[bottom][rounds])

评分

参与人数 1荣誉 +2 鱼币 +1 收起 理由
zhangjinxuan + 2 + 1

查看全部评分

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

使用道具 举报

发表于 2022-8-20 16:32:58 | 显示全部楼层
         你得把题目要求也贴出来,否则,不知道你的代码要干什么。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-21 11:41:38 | 显示全部楼层
本帖最后由 傻眼貓咪 于 2022-8-21 11:43 编辑

我不知道我解说的好不好,但尽量...

你的代码是很多很多人都用的方法之一:边界往内读取数据,所谓的边界说白了就是上下左右四方(分别是 top、bottom、right 和 left),题目要求:请按照顺时针螺旋顺序输出矩阵中的所有元素,得知:
(一)初始位置为左上方
(二)四方边界最初的位置为:
          -> 最左是第 0 位置,最右是第 3 位置(也就是 cols - 1)
          -> 最上是 0,最下是 2(rows - 1)

题解很简单:
你可以想象矩阵第一个位置(也就是如上所说的初始位置为左上方)有个机器人,用来读取走过的路线数据,每次 while 循环机器人都会重复执行往右、往下、往左、和往上四个步骤,每次循环后,边界往内缩小一格(上下左右都往内缩),表示已经走过的路线不再重复。直到左右边界相遇交叉或者上下边界相遇交叉,证明已经无法再缩小了,则退出循环。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-21 12:10:43 | 显示全部楼层
读懂了,但要解释感觉有点难
观察题目要求输出,不难想到,题目要求把数组变成矩阵,再按
1,  2,   3,  4
5,  6,   7,  8
9, 10, 11, 12
这种顺序依次打印矩阵元素
你再仔细观察这个顺序,会发现它其实重复着从左到右,从上到下,从右到左,从下到上的顺序,那么就可以开始写代码
代码中定义了四个顶点,左,上,右,下,左和上为0,右和下分别为矩阵的长宽,减一是因为列表下标从0开始
接着进入循环
    for col in range(left,right+1):
        result.append(matrix[top][col])

    for row in range(top+1,bottom+1):
        result.append(matrix[row][right])
第一个for循环从左到右遍历矩阵第一行的元素,此时top为0,right + 1是因为range不包含右边边界,比如range(0, 5)为0, 1, 2, 3, 4,所以right+1才能包含最右边的元素
那么这个循环就把矩阵第一行的1, 2, 3, 4这四个元素放进result中
第二个for循环从上到下遍历矩阵最后一列。top + 1是如果使用range(top, bottom + 1),就会把matrix[0][3]到matrix[2][3]添加进result,而matrix[0][3]在第一个循环就已经添加进result,再添加会导致重复
那么这个循环就把矩阵最后一列(不包括第一行的4)8, 12这两个元素放进result
至此,从左到右,从上到下两步完成,接下来要执行从右到左,从下到上的顺序
接着是判断四个边界有没有颠倒,left是不是在right的左边(小于right),top是不是在bottom的上面(小于bottom),没有的话就下一步
for col in range(right-1,left,-1):
            result.append(matrix[bottom][col])
range的步长为-1,表示从大到小,例如range(5, 0, -1)为5, 4, 3, 2, 1
那么在这里,代码将矩阵最后一行倒数第二列到最后一行第二列的元素放进result,从倒数第二列开始是因为最后一列已经被上一个循环放进result,到第二列是因为range不包含left,就像我上面range(5, 0, -1)的例子,结果不含0
那么这里,就是把矩阵最后一行的11, 10放进result中,完成了从右到左的步骤
最后
for row in range(bottom,top,-1):
            result.append(matrix[row][left])
代码将矩阵最后一行的第一列到第二行的第一列放进result,到第二行是因为第一行的第一列已经被第一个循环放进result,还是那句话,range生成的数列不包括top
那么这里就是把矩阵第一列(不包括第一行第一列)的9, 5放进result,完成了从下到上的步骤
此时矩阵内还剩最中间一个2x1的小矩阵[6, 7]没有被操作,仔细观察,这个小矩阵的四个边界,left, right, top, bottom,left和top都比原来的大矩阵的left和top大1,right和bottom都比原来的大矩阵小1。
所以最后就是left和top加1,right和bottom减1。并重复之前从左到右,从上到下,从右到左,从下到上的顺序

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

使用道具 举报

发表于 2022-8-21 14:16:47 | 显示全部楼层
看起来太麻烦了,我用递归给你简单写一个新思路,一目了然。
def tans90(arr):
    res = []
    for line in list(zip(*arr))[::-1]:
        res.append(list(line))
    return res

def clockwise(arr):
    if not arr:
        return []
    else:
        return arr.pop(0) + clockwise(tans90(arr))

if __name__ == '__main__':
    atrix = [[1, 2, 3, 4],
             [5, 6, 7, 8],
             [9, 10, 11, 12]]
    print(clockwise(atrix))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-21 14:58:06 | 显示全部楼层    本楼为最佳答案   
我的思路是这样:
往右往下往左往上走一圈为一个rounds
用for循环设置rounds参数限制位置
用while循环分别走四个方向并打印(也可以将元素输出到列表啊啥的)

matrix = [[1,2,3,4,5],
          [6,7,8,9,0],
          [11,12,13,14,15],
          [16,17,18,19,20],
          [21,22,23,24,25],
          [26,27,28,29,30]]
# 获取列表长度6
rows = len(matrix)
# 获取列表宽度5
cols = len(matrix[0])

for rounds in range(3):
    # 将位置参数初始化为第rounds圈,第一位置为[rounds][rounds]
    left = top = rounds
    # 右边界限为列表宽度-圈数-1
    right = cols - rounds - 1
    # 底部界限为列表长度-圈数-1
    bottom = rows - rounds - 1
    # 判定是否还有继续循环的必要,left>=right且top>=bottom则跳出
    if left >= right and top >= bottom:
        break
    # 顶部为第一序列
    while left <= right:
        # 输出第top行第left列
        print(matrix[top][left])
        # 位置往右移动
        left += 1
    # 右边为第二序列
    while top < bottom:
        # 位置往下移动
        top += 1
        # 输出top行right列
        print(matrix[top][right])
    while right > rounds:
        # 位置往左移动
        right -= 1
        # 输出bottom行right列
        print(matrix[bottom][right])
    while bottom > rounds+1:
        # 位置往上移动
        bottom-=1
        # 输出bottom行rounds列
        print(matrix[bottom][rounds])
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2022-8-22 16:11:19 | 显示全部楼层
鱼cpython学习者 发表于 2022-8-21 12:10
读懂了,但要解释感觉有点难
观察题目要求输出,不难想到,题目要求把数组变成矩阵,再按
1,  2,   3,  4 ...

虽然还不能完全理解,但是稍微清晰了一点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-22 16:14:30 | 显示全部楼层
鱼cpython学习者 发表于 2022-8-21 12:10
读懂了,但要解释感觉有点难
观察题目要求输出,不难想到,题目要求把数组变成矩阵,再按
1,  2,   3,  4 ...

我晕   点错人了,本来是选你最佳答案了,手误,不好意思啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-22 22:24:47 | 显示全部楼层
wangyanren 发表于 2022-8-22 16:14
我晕   点错人了,本来是选你最佳答案了,手误,不好意思啊

没事,理解就行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 14:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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