算法学习(4)数学问题求解系列(1)求解完数

前言

不知不觉,已经有3天多没有写博客了,意味着我又很多天没有码代码了……学编程最重要的一点,就是Keep Coding Everyday。我现在有深刻体会了!今天要写的程序非常简单,而我却花了很长时间去写,说明熟练度远远不够……是的,现在的生活很忙碌了,很多要兼顾,但自我提升,不都是各种时间协调,安排出时间来的吗?现在哪有只需要学习其他都不用考虑的生活啊,当然, 有也一定很无聊。希望接下来大家多多监督,这个博客,我肯定是不会放的,即使再忙!

系列说明

接下来一段时间,都会是用编程求解数学问题,这些问题相对简单,很适合练手。

问题

求解10000以内的所有完数。

名词解释

完数,就是它的所有因子,加起来,等于它这个数。如 6 = 1 + 2 + 3 6 = 1+2+3 6=1+2+3

编程思路

  1. 求解一个数的所有因子
  2. 判断这些因子相加是否等于这个数本身

实现代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2019-04-03 10:32:53
# @Author  : Promise (promise@mail.ustc.edu.cn)
# @Link    : ${link}
# @Version : $Id$


def findPefectNum():
    factorList = []  # 理论上因子个数是未定的
    perfectNumberConut = 0
    for i in range(2, 10000):
        s = i  # 用于储存检验的这个数
        count = 0  # 计数的变量
        for j in range(1, i//2+1):
            if i % j == 0:
                factorList.append(j)  # 采用append(),不用考虑因素个数问题
                s -= j
                count += 1
                if s < 0:
                    break  # 当s小于零,说明这个整数不可能是完数了
        if s == 0:  # 说明找到完数了
            perfectNumberConut += 1
            print('第', perfectNumberConut, '个完数:', i)


findPefectNum()

运行结果

运行结果

代码分析

  1. 第二个for循环里面,如果 s &lt; 0 s &lt; 0 s<0了,说明这个数肯定不是完数,跳出循环,提高效率
  2. 同样是第二个for, j 的终点设为 i 的一半,是因为任何数,都不会有大于自身一半的因数(这个数自身除外,想想为什么,你会发现很有趣!)

经验总结

出师不利,这个算法用了错误的学习方法,我先看了教材的解法,然后希望跟之前写排序算法一样,默写出来……但这样其实反而拖慢我自己的速度……因为这种简单问题,照着编程思路,很快就可以写出来的,或许一开始效率不行,但之后再调整就好了。
**另外!!!**教材再次有出错的代码,跟着它打,我也跟着错了……

多余的分析

下图的代码,是用C++写的,在一开始,程序假设了因子最多30个,所以有

long p[30];

但实际上,在运行过程中,有些数的因子数不止有30个,所以会报错(索引溢出)
于是,在上面我自己的程序,我改为不确定数组个数了。理论上,这会拖慢运行速度,但相比莫名的程序出错,我觉得这个代价可以接受。
最后再吐槽一句:不严谨的教材害死人……
教材的解法

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值