与回文数相似的例子,CS61A第一章的例子1.1逆序对
本帖最后由 ling830 于 2026-7-20 10:48 编辑'''from urllib.request import urlopen
shakespeare = urlopen('http://composingprograms.com/shakespeare.txt')
'''
#上面的网站不稳定,我把shakespeare.txt下载到了同一文件夹内
# 打开并读取本地文件
with open('shakespeare.txt', 'r', encoding='utf-8') as f:
# 读取所有内容并拆分为单词集合
# 注意:split() 默认会处理换行符和空格
words = set(f.read().split())
# 查询长度为 6 且其逆序词也存在于集合中的单词
# 使用集合推导式
result = {w for w in words if len(w) == 6 and w[::-1] in words}
# 打印结果
print(result)
中文版电子书籍
https://composingprograms.netlify.app/1/1 您的代码基本思路正确,但存在一个逻辑错误:if len(w) == 6 and w in words 中,w in words 永远为 True,因为 w 本身就是从 words 里取出的,所以条件退化为「选出所有长度为 6 的单词」,而非您期望的「单词与其逆序词都在集合中」。
修正方法:将判断条件改为 if len(w) == 6 and w[::-1] in words,检查逆序词是否也存在于集合中。
修正后的代码:
with open('shakespeare.txt', 'r', encoding='utf-8') as f:
words = set(f.read().split())
# 查询长度为6且其逆序词也在集合中的单词
result = {w for w in words if len(w) == 6 and w[::-1] in words}
print(result)
此外,注意:
[*] 原文件若包含标点(如逗号、句点),split() 会保留它们,可能导致单词「长短」计算含标点。如需更精确匹配,可使用正则提取纯字母单词。
[*] 若文本中存在重复单词,集合本身会自动去重,无需额外处理。
如果问题已解决,请忽略此提醒。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 返回的结果是,这个回文数
{'reward', 'diaper', 'drawer', 'repaid', 'redder'}
ling830 发表于 2026-07-20 10:24
返回的结果是,这个回文数
{'reward', 'diaper', 'dr ...
您反馈的结果是修正后的正确输出,不过这里有个概念需要澄清:您得到的结果并不是**回文数**,而是**与其逆序词同时存在于集合中的单词**(即某个单词和它反转后的单词都在列表中)。例如:
- reward 的逆序是 drawer,二者都在集合中
- diaper 的逆序是 repaid,二者都在集合中
- redder 实际上是回文(正反一样),也符合条件(自身逆序也在集合中)
而真正的回文是指正反一样,如 "redder"。但其余几个单词不是回文。您可以把它们称为**逆序对**或**anadromes**(反转异序词)。您的代码已正确完成 CS61A 例子的任务,无需修改。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 的确,这是文字。不是回文数。不过是我第一反应想起了小甲鱼说的回文数。 ling830 发表于 2026-07-20 10:32
的确,这是文字。不是回文数。不过是我第一反应想起了 ...
您说得对!小甲鱼老师讲过的回文数(比如 12321、1221 这种正反读一样的数字)是非常经典的概念。而 CS61A 这个例子拓展到了字符串,寻找的是「互为逆序的单词对」,其中有些单词自身就是回文(如 redder),但更多的是两个不同的单词互为逆序(如 reward 和 drawer)。
所以您可以这样理解:
- 回文数 / 回文字符串:正反完全相同(如 12321、level)
- 逆序词对:两个不同的字符串,其中一个反转后等于另一个(如 reward <-> drawer)
您的代码已经正确实现了后者,很棒!如果以后想求真正的回文字符串,只需将条件改成 `w == w[::-1]` 即可。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]