再次练习查找完美数,找出 1-1000 中的所有完美数。
-
Python 官网:https://www.python.org/
-
Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单……
地址:https://lqpybook.readthedocs.io/
自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
—— 华罗庚
- My CSDN主页、My HOT博、My Python 学习个人备忘录
- 好文力荐、 老齐教室
本文质量分:
CSDN质量分查询入口:http://www.csdn.net/qc
- ◆找出 1-1000 中的所有完美数
- 1、完美数
- 1.1 完美数定义
- 1.2 完美数都有哪些
- 2、“所有的真因子” ≠ “因子分解”
- 3、解题思路
- 4、代码实现
- 4.1 for 轮询完数
- 4.2 列表解析
- 4.3 算法“优化”
- 5、完整源码
◆找出 1-1000 中的所有完美数
1、完美数
要查找完美数,首先要明白完美数定义。网搜一波,摘录如下:
1.1 完美数定义
完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。如果一个数恰好等于它的因子之和,则称该数为“完全数”。完数即完美数,所有的偶完数都可以表达为 2 的一些连续正整数次幂之和,除 6 以外的偶完数,还可以表示 成连续奇数的立方和。
(完美数百科词条,可以点击蓝色文字跳转查阅更多。)
1.2 完美数都有哪些
完数有很多,比如 6、28、496、8128、33550336、8589869056 等。目前,相关研究者已经找到 51 个完全数。
2、“所有的真因子” ≠ “因子分解”
“所有的真因子”与“因子分解”,对于大多数整数是不一样的。我就是理解混淆了,导致写出的代码判定不出完美数。如:
整数 4 :分解因子是,2 2。所有真因子是,1 2。
整数 6 :分解因子是,2 3。所有真因子是,1 2 3。
整数 24 :分解因子是,2 2 2 3。所有真因子是,1 2 3 4 6 8 12。
整数 28 :分解因子是,2 2 7。所有真因子是,1 2 4 7 14。
3、解题思路
在我刚学会使用 if、while、for 判断循环语句的时候,蹒跚着做过一个练习——“找寻完数”,代码稚嫩直白。😋
可以点击蓝色文字跳转翻阅。
弄明白了一个自然数的“所有真因子”,就可以分析解题了。
要查找给定范围的全部完美数,首先得判定一个整数它是不是完数。
判定一个整数是否完数,就要找出它的所有“真因子”并求和与整数本身比较,如果相等则是完数。
- 判定完数函数
def is_perfect_number(n):''' 判定完数 '''if n < 6:return # 据完数定义,小于6的自然数都不是完数。factors = [] # 整数n的真因子集合初值。for i in range(1, n): # 常规写法。if n%i == 0:factors.append(i) # 收集自然数n的真因子。if sum(factors) == n:print(f"{n:>9}:{factors}")return n # n是完数,返回n,非则返回None。后面两行可以不写,python函数默认没有return语句返回空。else:return
- 列表解析给定范围的完数
以上面的完数判定完数函数,以列表形式的方式解析给定范围内的全部完数。
def find_perfect_numbers(num):''' 寻找完数 '''perfect_numbers = [i for i in range(num+1) if is_perfect_number(i)] # 解析完数列表。return ', '.join(map(str, perfect_numbers)) # 返回用英文逗号拼接的完数集合字符串。
4、代码实现
4.1 for 轮询完数
def is_perfect_number(n):''' 判定完数 '''cls = lambda: print(' '*50, end='\r') # 清除" 正在计算…… '字符单行函数。print(f"{' 正在计算…… ':~^46}", end='\r')if n < 6:return # 据完数定义,小于 6 的自然数都不是完数。factors = [i for i in range(1, n) if not n%i] # 列表解析整数 n 的真因子集合。#factors = [i for i in range(n-1, 0, -1) if not n%i] # 也可以倒序解析。if sum(factors) == n:cls() # 调用清除屏幕函数。print(f"{n:^6}: {factors}")return n # n 是完数,返回 n ,非则返回 None 。cls() # 调用清除屏幕函数。
4.2 列表解析
- 列表解析出给定范围内的的所有完美数
perfect_numbers = [i for i in range(num+1) if is_perfect_number(i)] # 解析完数列表。
4.3 算法“优化”
从大到小找寻“真因子”,可以在总和大于整数 n 时,停止遍历轮询,看似可以优化。
- “优化”
def is_perfect_number(n):''' 判定完数 '''cls = lambda: print(' '*50, end='\r') # 清除" 正在计算…… '字符单行函数。print(f"{' 正在计算…… ':~^46}", end='\r')if n < 6:return # 据完数定义,小于 6 的自然数都不是完数。#factors = [i for i in range(1, n) if not n%i] # 列表解析整数 n 的真因子集合。factors = []for i in range(n-1, 0, -1): # 也可以倒序,从大到小遍历轮询,真因子和大于 n 即可退出遍历。if not n%i:factors.append(i)if sum(factors) > n:return # “真因子”集合的总和已大于 n ,即 n 非完数,返回 None 。if sum(factors) == n:cls() # 调用清除屏幕函数。print(f"{n:^6}: {factors}")return n # n 是完数,返回 n ,非则返回 None 。cls() # 调用清除屏幕函数。
- 列表解析
- 正序
factors = [i for i in range(1, n) if not n%i] # 正序列表解析整数 n 的真因子集合。
- 倒序
factors = [i for i in range(n-1, 0, -1) if not n%i] # 倒序列表解析整数 n 的真因子集合。
- 结语:
为什么,列表解析比看似优化的算法,效率还高用时还省?🤨
这都是因为 Python 的解析式,底层算法比 for 遍历轮询要高效得多,代码优化的那一点点,根本没敌过解析式。
5、完整源码
(源码较长,点此跳过源码)
#!/sur/bin/nve python
# coding: utf-8def is_perfect_number(n):''' 判定完数 '''cls = lambda: print(' '*50, end='\r') # 清除" 正在计算…… '字符单行函数。print(f"{' 正在计算…… ':~^46}", end='\r')if n < 6:return # 据完数定义,小于 6 的自然数都不是完数。factors = [i for i in range(1, n) if not n%i] # 列表解析整数 n 的真因子集合。#factors = [i for i in range(n-1, 0, -1) if not n%i]'''factors = []for i in range(n-1, 0, -1): # 也可以倒序,从大到小遍历轮询,真因子和大于 n 即可退出遍历。if not n%i:factors.append(i)if sum(factors) > n:return # “真因子”集合的总和已大于 n ,即 n 非完数,返回 None 。'''if sum(factors) == n:cls() # 调用清除屏幕函数。print(f"{n:^6}: {factors}")return n # n 是完数,返回 n ,非则返回 None 。cls() # 调用清除屏幕函数。def find_perfect_numbers(num):''' 寻找所有完数 '''print(f"{'查找过程:':>4}\n\n{'整数':^4}: “真因子”集合")perfect_numbers = [i for i in range(num+1) if is_perfect_number(i)] # 解析完数列表。return ', '.join(map(str, perfect_numbers)) # 返回用英文逗号拼接的完数集合字符串。if __name__ == '__main__':from time import timeperfect_number = '完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。\n 如果一个数恰好等于它的因子之和,则称该数为“完全数”。完数即完美数,所有的偶完数都可以表达为2的一些连续正整数次幂之和,除6以外的偶完数,还可以表示成连续奇数的立方和。'proper_divisor = '真因数是指一个自然数除自身以外的因数。' # factor、divisor俩单词皆有“因子”释义。n = int(input(f"\n\n{' 完美数查找 ':=^45}\n\n{' 完美数定义 ':~^45}\n{'完美数:':>8}{perfect_number}\n{'真因子:':>8}{proper_divisor}\n{'':~^50}\n\n{'输入范围(如1000):':>14}"))print(f"\n{'':=^50}\n\n")start_sec = time()print(f"\n\n{'':~^50}\n\n{'':>4}自然数1~{n}中的完美数:{find_perfect_numbers(n)}\n\n{'':~^50}\n{f'程序用时{time()-start_sec:.2f}秒':^45}\n")
上一篇: 罗列博文笔记总索引列表( Python 代码打造小 AI ,自动生成“我的博文笔记总索引”博文 HTML5 源码文本)
下一篇: “递归三要素”寻踪(浅析递归“精典”框架,领略递归优雅秀气;看到有“递归算法优化”的操作,余试剖之)
我的HOT博:
本次共计收集 197 篇博文笔记信息,总阅读量 31.53w,平均阅读量 1600。已生成 20 篇阅读量不小于 3000 的博文笔记索引链接。数据采集于 2023-04-22 22:06:31 完成,用时 4 分 54.07 秒。
- 让QQ群昵称色变的神奇代码
( 53118 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/122566500
点赞:22 踩 :0 收藏:74 打赏:0 评论:16
本篇博文笔记于 2022-01-18 19:15:08 首发,最晚于 2022-01-20 07:56:47 修改。 - ChatGPT国内镜像站初体验:聊天、Python代码生成等
( 45992 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/129035387
点赞:123 踩 :0 收藏:783 打赏:0 评论:73
本篇博文笔记于 2023-02-14 23:46:33 首发,最晚于 2023-03-22 00:03:44 修改。 - pandas 数据类型之 DataFrame
( 7915 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/124525814
点赞:6 踩 :0 收藏:23 打赏:0 评论:0
本篇博文笔记于 2022-05-01 13:20:17 首发,最晚于 2022-05-08 08:46:13 修改。 - 罗马数字转换器|罗马数字生成器
( 6328 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/122592047
点赞:0 踩 :0 收藏:1 打赏:0 评论:0
本篇博文笔记于 2022-01-19 23:26:42 首发,最晚于 2022-01-21 18:37:46 修改。 - Python字符串居中显示
( 6002 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/122163023
点赞:1 踩 :0 收藏:5 打赏:0 评论:1
本篇博文笔记于 2021-12-26 23:35:29 发布。 - 斐波那契数列的递归实现和for实现
( 5272 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/122355295
点赞:4 踩 :0 收藏:2 打赏:0 评论:8
本篇博文笔记于 2022-01-06 23:27:40 发布。 - 练习:字符串统计(坑:f‘string‘报错)
( 4846 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/121723096
点赞:0 踩 :0 收藏:1 打赏:0 评论:0
本篇博文笔记于 2021-12-04 22:54:29 发布。 - 练习:尼姆游戏(聪明版/傻瓜式•人机对战)
( 4560 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/121645399
点赞:14 踩 :0 收藏:42 打赏:0 评论:0
本篇博文笔记于 2021-11-30 23:43:17 发布。 - 个人信息提取(字符串)
( 4455 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/124244618
点赞:1 踩 :0 收藏:8 打赏:0 评论:0
本篇博文笔记于 2022-04-18 11:07:12 首发,最晚于 2022-04-20 13:17:54 修改。 - 回车符、换行符和回车换行符
( 4292 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/123109488
点赞:0 踩 :0 收藏:2 打赏:0 评论:0
本篇博文笔记于 2022-02-24 13:10:02 首发,最晚于 2022-02-25 20:07:40 修改。 - python清屏
( 4178 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/120762101
点赞:0 踩 :0 收藏:5 打赏:0 评论:0
本篇博文笔记于 2021-10-14 13:47:21 发布。 - 密码强度检测器
( 3838 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/121739694
点赞:1 踩 :0 收藏:4 打赏:0 评论:0
本篇博文笔记于 2021-12-06 09:08:25 首发,最晚于 2022-11-27 09:39:39 修改。 - 罗马数字转换器(用罗马数字构造元素的值取模实现)
( 3781 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/122608526
点赞:0 踩 :0 收藏:0 打赏:0 评论:0
本篇博文笔记于 2022-01-20 19:38:12 首发,最晚于 2022-01-21 18:32:02 修改。 - 练习:班里有人和我同生日难吗?(概率probability、蒙特卡洛随机模拟法)
( 3506 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/124424935
点赞:1 踩 :0 收藏:2 打赏:0 评论:0
本篇博文笔记于 2022-04-26 12:46:25 首发,最晚于 2022-04-27 21:22:07 修改。 - 练习:生成100个随机正整数
( 3464 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/122558220
点赞:1 踩 :0 收藏:3 打赏:0 评论:0
本篇博文笔记于 2022-01-18 13:31:36 首发,最晚于 2022-01-20 07:58:12 修改。 - 我的 Python.color() (Python 色彩打印控制)
( 3308 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/123194259
点赞:2 踩 :0 收藏:7 打赏:0 评论:0
本篇博文笔记于 2022-02-28 22:46:21 首发,最晚于 2022-03-03 10:30:03 修改。 - Python列表(list)反序(降序)的7种实现方式
( 3223 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/128271700
点赞:4 踩 :0 收藏:10 打赏:0 评论:8
本篇博文笔记于 2022-12-11 23:54:15 首发,最晚于 2023-03-20 18:13:55 修改。 - 练习:仿真模拟福彩双色球——中500w巨奖到底有多难?跑跑代码就晓得了。
( 3162 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/125415626
点赞:3 踩 :0 收藏:4 打赏:0 评论:3
本篇博文笔记于 2022-06-22 19:54:20 首发,最晚于 2022-06-23 22:41:33 修改。 - 聊天消息敏感词屏蔽系统(字符串替换 str.replace(str1, *) )
( 3035 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/124539589
点赞:3 踩 :0 收藏:3 打赏:0 评论:3
本篇博文笔记于 2022-05-02 13:02:39 首发,最晚于 2022-05-21 06:10:42 修改。 - Linux 脚本文件第一行的特殊注释符(井号和感叹号组合)的含义
( 3005 阅读)
博文地址:https://blog.csdn.net/m0_57158496/article/details/123087606
点赞:0 踩 :0 收藏:4 打赏:0 评论:3
本篇博文笔记于 2022-02-23 13:08:07 首发,最晚于 2022-04-04 23:52:38 修改。
精品文章:
- 好文力荐:齐伟书稿 《python 完全自学教程》 Free连载(已完稿并集结成书,还有PDF版本百度网盘永久分享,点击跳转免费🆓下载。)
- OPP三大特性:封装中的property
- 通过内置对象理解python'
- 正则表达式
- python中“*”的作用
- Python 完全自学手册
- 海象运算符
- Python中的 `!=`与`is not`不同
- 学习编程的正确方法
来源:老齐教室
◆ Python 入门指南【Python 3.6.3】
好文力荐:
- 全栈领域优质创作者——[寒佬](还是国内某高校学生)博文“非技术文—关于英语和如何正确的提问”,“英语”和“会提问”是编程学习的两大利器。
- 【8大编程语言的适用领域】先别着急选语言学编程,先看它们能干嘛
- 靠谱程序员的好习惯
CSDN实用技巧博文:
- 8个好用到爆的Python实用技巧
- python忽略警告
- Python代码编写规范
- Python的docstring规范(说明文档的规范写法)