本帖最后由 txxcat 于 2020-5-4 21:38 编辑
首先在不看答案的情况下写了一段代码:
- '''Perfect number'''
- for i in range(1,10000):
- a=0
- for j in range(1,i//2+1):
- if i%j==0:
- a+=j
- if i==a:
- print(i)
复制代码
运行起来没问题,再和答案的代码进行了对比,发现虽然我写的简单,但是效率不高,因为除数的范围到了被除数的一半,越往后,运算量越大。
答案的代码就减少了不少,除数范围只有平方根以下的数,减少了不少运算量,为什么这么算,以28为例子来说明:
28的因子有:1、2、4、7、14,除了1可以分为2*14、4*7,可见其实因子数除了1以外都是成对出现的,相乘等于被除数本身,所以找到分界点就行了,然后除以算出来的因子得到对应的另一个因子数。分界点就是平方根,这点好理解吧。后面得到对应因子的判断中,排除1的原因已经直到了,但是为什么num // factor != factor?这是防止平方根正好也是因子的情况,不排除掉就会重复多算了一个因子。
根据这个算法优化了一下代码,
- for num in range(2, 10000): #从2开始算可以避开这个算法的一个小bug
- result = 1 #1是所有整数的因子,所以1就不进入循环直接带入可以少算一轮
- for factor in range(2, int(num**0.5) + 1): #从2开始循环,原代码的1的判断可以去掉了
- if num % factor == 0:
- result += (factor+(num / factor if factor**2!=num else 0 )) #直接把成对因子加入,平方根是因子就只算1个。
- if result == num:
- print(num)
复制代码