码迷,mamicode.com
首页 > 其他好文 > 详细

完全数

时间:2016-06-12 23:42:25      阅读:403      评论:0      收藏:0      [点我收藏+]

标签:完全数

程序地址:http://www.cheemoedu.com/exercise/13


问题描述:

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。例如,第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。第二个完全数是28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。
编程求10000以内的完全数。


我的代码:

import datetime
starttime = datetime.datetime.now()
def perfect(n):
    m=[i for i in range(1,n/2+1) if n%i==0]
    if sum(m)==n:
        print n
for k in range(1,10000):
    perfect(k)
endtime = datetime.datetime.now()
print (endtime - starttime).seconds


我的思路:

首先定义一个求一个数的所有约数的函数(这个函数一定要尽量快速简单,否则计算100内的完全数还行,范围大一点的话就会奇慢无比),然后用for循环遍历即可;


之前淘汰的代码:

def perfect(n):
    a=[]
    for i in range(1,n+1):
        for j in range(n,0,-1):
            if i*j==n:
                a.append(i)
    a.pop()
    if sum(a)==n:
        print n
for k in xrange(1,10000):
    perfect(k)


思路其实很简单,实现起来也容易,但是想要很快速的显示完全数却是个不简单的任务,起初,我没觉得难(100以内的秒出),可是范围增大到1000时,速度明显慢了很多,到10000时,等了10几分钟都没反应,后来我进行了优化,根据“完全数都是以6或8结尾(如果以8结尾,那么就肯定是以28结尾)”原理,将范围缩减到了1000多个数,可是还是很慢很慢,后来又根据“除6以外的完全数,它们被3除余1、9除余1、还有1/2被27除余1(百科上看的)”将范围缩减到了120多个,但是还是慢(长达14秒),这才意识到是代码写的有问题,想来想去就写了最上面的那个,它的结果为:

E:\python\python.exe D:/pycharm/python/奇猫百题/完全数.py

6

28

496

8128

6    #运行时间为6秒

虽然计算10000以内的还算可以,但是在增加一个数量级又会很慢,没辙了,这时我所能想到的最快的方法了。


示例代码:

def isPerfectNumber(n):
    a = 1
    b = n
    s = 0
    while a < b:
        if n % a == 0:
            s += a + b
        a += 1
        b = n / a
    if a == b and a * b == n:
        s += a
    return s - n == n
for k in range(2, 10000):
    if isPerfectNumber(k):
        print k

代码分析:

示例代码的while循环是一边算传入数的约数,一边求其和,然后判断是否满足关系,满足的话就多加个a(两个约数相等且积为原数),其次还要减去n(第一次循环时加上了b),最后再返回完全数;

虽然a是递增的,但是b的范围几乎是折半的,而且比较的是a和b的大小,所以它每一个数循环的次数都很少,而且不用再另算总和,所以比我的要快,事实证明,在计算10000以内的完全数时几乎是秒出,而100000时才用了11秒,真的比我的要好很多。


完全数

标签:完全数

原文地址:http://jmbzs.blog.51cto.com/9449309/1788440

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!