100个python算法超详细讲解:完数

1.问题描述
求某一范围内完数的个数。
如果一个数等于它的因子之和,则称该数为“完数”(或“完全数”)。例
如,6的因子为1、2、3,而6=1+2+3,因此6是“完数”。
2.问题分析
根据完数的定义,解决本题的关键是计算出所选取整数i(i的取值范围
不固定)的因子(因子就是所有可以整除这个数的数),然后将各因子累加
到变量s(记录所有因子之和),若s等于i,则可确认i为完数,反之则不是完
数。
3.算法设计
对于这类求某一范围(本题范围不固定,在编程过程中采用键盘输入的
方式)内满足条件的数的问题,一般采用遍历的方式,即一个一个地去判断
给定范围内的数值是否满足条件,这一过程可利用循环来实现。
本题的关键是求出选取数值i的因子,即从1到i-1范围内能整除i的数。看
某一个数j是不是i的因子,可利用语句“if i%j==0”进行判断,求某一个数的所
有因子,需要在1到i-1范围内进行遍历,同样采用循环实现。因此,本题从
整体上看可利用两层循环来实现。外层循环控制该数的范围为2~n;内层循
环j控制除数的范围为1~i,通过判断i对j取余是否等于0,找到该数的各个因
子。程序段如下:

i = 2 # 变量 i 控制选定数的范围
while i <= n:
...
for j in range(i):
...
if s == i: # 判断因子之和是否和原数相等
# 输出当前i是完数
i += 1

对于某个选定的数,将求得的各因子累加到变量s(累加过程中用到s的
初值,故s初值为0)之后,s的值发生改变,若直接将下一个选定数的因子加
到s上,得到的值并非所求(此时s的初值不是0而是上一个选定数的因子之
和)。因此每次判断下一个选定数之前,必须将变量s的值重新置为0。编程
过程中一定要注意变量s重新置0的位置,如果语句放的位置不正确,得到的
结果也不是正确结果。
注意: Python语言中的整数问题经常涉及判断两个数是否相等或某变量
(或表达式)是否满足某一条件的情况,对于这类问题,初学者经常会出现
混用赋值符号“=”与等于号“==”的情况。
赋值符号“=”的优先级别低于其他的运算符,所以对该运算符往往最后
读取。它的作用是将一个表达式的值赋给一个变量(左值)。左值必须能够
被修改,不能是常量。如while i=10的作用是将右值“10”赋给左值i,每次判
断i的值都为10,故表达式的值为非0,即判定条件为真,导致程序进入死循
环。
等于号“==”是关系运算符的一种,结果只有True或False两种。它的作用
是用来判断等号“==”两边参与运算的值是否相等,若相等,则返回True,否
则返回False。如while i==10的作用是判断变量i的值是否等于10,若相等,表
达式的值为True,否则为False,当表达式为真,程序继续执行循环体语句,
否则结束循环。
4.确定程序框架
程序流程图如图所示。 

5.完整的程序

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 完数
if __name__=="__main__":
	n = int(input("请输入所选范围上限: "))
	变量 控制选定数的范围
	i = 2 # 变量 i 控制选定数的范围
	while i <= n:
		s = 0 # s记录累加因子之和,保证每次循环时s的初值为0
		j = 1 # j 控制除数范围
		for j in range(i):
			if j != 0 and i % j == 0: # 判断 j 是不是 i 的因子
				s += j # 因子和
				if s == i: # 判断因子之和是否和原数相等
					print("2到%d之间的完数:%d" %(n, i))
					i += 1

6.运行结果
程序运行结果如图所示。

 7.问题拓展
上述程序中,求某数的因子时采用从1到i-1范围内进行遍历的方法,一
个数一个数地去试。这种方法可以做到没有遗漏,但是效率不高。
对于某一整数来说,其最大因子为n/2(此时n为偶数,若n为奇数,其最
大因子小于n/2),在n/2~n-1范围内没有数据可以整除此数。据此,我们可
以把遍历范围缩小至1~n-1,这样程序效率可以提高一倍。相应的程序如
下:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 完数
if __name__=="__main__":
	n = int(input("请输入所选范围上限: "))
	i = 2 # 变量 i 控制选定数的范围
	print(n)
	while i <= n:
		s = 0 # s记录累加因子之和,保证每次循环时s的初值为0
		j = 1 # j 控制除数范围
		while j <= (n // 2):
			判断 是不是 的因子
			if j != 0 and i % j == 0: # 判断 j 是不是 i 的因子
				s += j # 因子和
				j += 1
				if s == i: # 判断因子之和是否和原数相等
					print("2到%d之间的完数:%d" %(n, i))
					i += 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lee达森

创作不易,感谢打赏!

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

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

打赏作者

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

抵扣说明:

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

余额充值