找出1-1000中的所有完美数

155 篇文章 3 订阅
75 篇文章 0 订阅

再次练习查找完美数,找出 1-1000 中的所有完美数。


【学习的细节是欢悦的历程】


  自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
            —— 华罗庚


等风来,不如追风去……


再次练习查找完美数
找出所有完美数
(找出 1-1000 中的所有完美数)


本文质量分:

91
本文地址: https://blog.csdn.net/m0_57158496/article/details/128571354

CSDN质量分查询入口:http://www.csdn.net/qc


目 录


◆找出 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-8


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]
    
    '''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 time
    perfect_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 秒。


  1. 让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 修改。
  2. 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 修改。
  3. 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 修改。
  4. 罗马数字转换器|罗马数字生成器
    ( 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 修改。
  5. Python字符串居中显示
    ( 6002 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122163023
    点赞:1   踩 :0  收藏:5  打赏:0  评论:1
    本篇博文笔记于 2021-12-26 23:35:29 发布。
  6. 斐波那契数列的递归实现和for实现
    ( 5272 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122355295
    点赞:4   踩 :0  收藏:2  打赏:0  评论:8
    本篇博文笔记于 2022-01-06 23:27:40 发布。
  7. 练习:字符串统计(坑:f‘string‘报错)
    ( 4846 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/121723096
    点赞:0   踩 :0  收藏:1  打赏:0  评论:0
    本篇博文笔记于 2021-12-04 22:54:29 发布。
  8. 练习:尼姆游戏(聪明版/傻瓜式•人机对战)
    ( 4560 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/121645399
    点赞:14   踩 :0  收藏:42  打赏:0  评论:0
    本篇博文笔记于 2021-11-30 23:43:17 发布。
  9. 个人信息提取(字符串)
    ( 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 修改。
  10. 回车符、换行符和回车换行符
    ( 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 修改。
  11. python清屏
    ( 4178 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/120762101
    点赞:0   踩 :0  收藏:5  打赏:0  评论:0
    本篇博文笔记于 2021-10-14 13:47:21 发布。
  12. 密码强度检测器
    ( 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 修改。
  13. 罗马数字转换器(用罗马数字构造元素的值取模实现)
    ( 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 修改。
  14. 练习:班里有人和我同生日难吗?(概率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 修改。
  15. 练习:生成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 修改。
  16. 我的 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 修改。
  17. 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 修改。
  18. 练习:仿真模拟福彩双色球——中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 修改。
  19. 聊天消息敏感词屏蔽系统(字符串替换 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 修改。
  20. 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 入门指南【Python 3.6.3】


好文力荐:


CSDN实用技巧博文:


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦幻精灵_cq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值