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