鱼C论坛

 找回密码
 立即注册
查看: 2876|回复: 4

[已解决]一个Py题:我看不懂报错内容

[复制链接]
发表于 2021-5-24 11:51:32 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 Peteryo01223 于 2021-5-24 11:56 编辑

题目:500个小孩,围成一个圈。从第一个小孩开始计数,每次逢3,或3的倍数,出圈,如:3/6/27/468等等。直到最后剩一个小孩,请问他(她)最初的编号是多少?
答案:
# 第一个类:kid
# 第二个类:circle
# kid 属性:编号gid,lefthand、righthand
# 圈属性:head 和 tail。
# 圈的行为:加入(add)一个小孩,移除(remove)一个小孩。

class Kid:
    def __init__(self, gid):
        self.gid = gid # 小孩属性之编号
        self.left = None # 小孩属性之左手
        self.right = None # 小孩属性之右手


class Circle:
    # 初始化的时候,定义圈的头和尾
    def __init__(self, count):
        self.head = None
        self.tail = None

        for i in range(count):
            self.add(Kid(i+1))

    def add(self, kid):
        # 向圈里,加入一个小孩
        if self.head is None and self.tail is None:
            self.head = kid
            self.tail = kid
            kid.left = kid
            kid.right = kid
        else:
            kid.left = self.head
            kid.right = self.tail
            self.head.right = kid
            self.tail.left = kid
            self.tail = kid

    def remove(self, kid):
        # 从圈里面移除一个小孩
        if kid is self.head:
            self.head = kid.left
        if kid is self.left:
            self.tail = kid.right

        kid.left.right = kid.right
        kid.right.left = kid.left
        kid.left = None
        kid.right = None


circle = Circle(500)
cur = circle.head # 指针指向开头
step = 1

while circle.head is not circle.tail:
    # 当圈里不只一个小孩的时候,就继续
    cur = cur.left
    if step % 3 == 0:
        circle.remove(cur.right)
    step += 1

print(circle.head.gid)

报错内容:
D:\PycharmProjects\learnpython\venv\Scripts\python.exe D:/PycharmProjects/learnpython/ch7/20210524a.py
Traceback (most recent call last):
  File "D:/PycharmProjects/learnpython/ch7/20210524a.py", line 58, in <module>
    circle.remove(cur.right)
  File "D:/PycharmProjects/learnpython/ch7/20210524a.py", line 41, in remove
    if kid is self.left:
AttributeError: 'Circle' object has no attribute 'left'
看不懂报错内容,请高手们指点迷津,谢谢~此题难度太大了,我实在不会改。
最佳答案
2021-5-24 12:18:09


Circle 类中的  remove 方法的第二个 if 条件 self.left 改成 self.tail 即可
    def remove(self, kid):
        # 从圈里面移除一个小孩
        if kid is self.head:
            self.head = kid.left
        if kid is self.tail:
            self.tail = kid.right

        kid.left.right = kid.right
        kid.right.left = kid.left
        kid.left = None
        kid.right = None

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

使用道具 举报

发表于 2021-5-24 12:18:09 | 显示全部楼层    本楼为最佳答案   


Circle 类中的  remove 方法的第二个 if 条件 self.left 改成 self.tail 即可
    def remove(self, kid):
        # 从圈里面移除一个小孩
        if kid is self.head:
            self.head = kid.left
        if kid is self.tail:
            self.tail = kid.right

        kid.left.right = kid.right
        kid.right.left = kid.left
        kid.left = None
        kid.right = None

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

使用道具 举报

 楼主| 发表于 2021-5-24 13:19:17 | 显示全部楼层
Twilight6 发表于 2021-5-24 12:18
Circle 类中的  remove 方法的第二个 if 条件 self.left 改成 self.tail 即可

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

使用道具 举报

 楼主| 发表于 2021-5-24 13:33:16 | 显示全部楼层
Twilight6 发表于 2021-5-24 12:18
Circle 类中的  remove 方法的第二个 if 条件 self.left 改成 self.tail 即可


多问你一句:第26-29行,我能四行合并如下么?
self.head = self.tail = kid.left = kid.right = kid
我试了试,Python 答案变成 1 了,感觉不能这么写。但是,我不懂背后的逻辑。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-24 13:42:18 | 显示全部楼层
Peteryo01223 发表于 2021-5-24 13:33
多问你一句:第26-29行,我能四行合并如下么?

我试了试,Python 答案变成 1 了,感觉不能这么写。 ...



可以这样写呀,而且最后值不会改变,是等价的

因为赋值操作,是将左边的值赋值给右边,所以这样相当于将 kid 依次赋值给了 kid.right、kid.left、self.tail、self.head

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-9 01:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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