Python实现完全数的示例详解
作者:?????? 发布时间:2021-11-21 20:09:30
一、前言
卷起来好吧,元旦已经过了,就开始写文章模式了。
这篇文章会对完全数的各种侦测进行详细解释。写作不易,支持一波~
二、完全数是什么
1、定义
老规矩,先来了解完全数是什么。
完全数,又称完美数,定义为:这个数的所有因数(不包括这个数本身)加起来刚好等于这个数。比如6就是完全数,因为6的因数有1,2,3(不包括6本身),1+2+3正好等于6。
所以如果有人给你扣6,那说明他在夸赞你十分完美(bushi。
完全数是一个叫毕达哥拉斯的提出来的,被誉为“最古老的数学问题”,这人还提出了我们熟悉的勾股定理和黄金比例。
目前一共找到了51个完全数,非常的稀有,比较小的有6、28、496、8128、33550336等等。
目前还没有人找到奇数完全数,也没有人能证明“没有奇数完全数”。但是,一个叫做奥斯丁·欧尔的人证明出来:要是有奇完全数,必须能表示成12x质数+1或者36x质数+9,并且在10^300以内没有奇完全数的存在。
完全数会越来越大,第39个完全数有25674127位数,如果用四号字字体打印出来,也能变成一本字典。
2、规律
这些数之间有没有一些规律呢?
有,并且很多。(以下规律仅仅是目前发现的完全数都符合这个定律,部分未证明)
第一,完全数都是以6或28结尾的。
第二,完全数都是三角形数,例如6可以表示成1+2+3,28可以表示成1+2+3+4+5+6+7。
第三,除了6以外都可以表示成连续隔2奇立方数之和。例如28表示成1^3+3^3,496表示成1^3+3^3+5^3+7^3。
第四,完全数的所有因数的倒数的和为2。例如6所有因数的倒数是1,1/2,1/3,1/6,相加为2。28所有因数的倒数是1,1/2,1/4,1/7,1/14,1/28,相加为2。
第五,完全数都可以表示成2的连续数次方之和。例如6可以表示成2^1+2^2,28可以表示成2^2+2^3+2^4。
第六,6以外的完全数经过碾转之后为1。碾转就是把他的各个位数相加一直到只剩一位数。例如28碾转数为:2+8=10,1+0=1。496碾转数为:4+9+6=19,1+9=10,1+0=1。
第七,6以外的完全数除以9一定余数为1。例如:28除以9=3…1,496除以9=55…1。
知道为啥有一个别名叫完美数了吧?太完美了!
3、梅森素数
之后又冒出来了一个梅森素数,这是欧几里得整出来的。我们定义P是一个质数,如果2^p-1也是质数,那么这个质数就是“梅森素数”。
知道梅森素数之后,把P带入公式2^(p-1)(2^p-1),咔咔一顿算,结果就是完全数。
我们想想是不是这样。
因为2是质数,2^2-1是3也是质数,那么3就是梅森素数。把2带入公式,咔咔一顿算结果就是6。
3是质数,2^3-1是7也是质数,那么7就是梅森素数。把3带入公式,咔咔一顿算结果就是28。
欧拉证明出来,所有完全数都符合这个形式。有了这个公式计算就更简便了。
三、版本(1.0):硬算
接下来,我们先写程序硬算一遍。
我们需要让程序找到一个数的每一个除了本身之外的因数,还要把它们都加起来,这些程序可以放在一个函数里面。之后再套上循环,数自增重复调用就行了。是不是很简单?
先完成找数的所有因数的效果。
我们要创建一个函数,用for循环和range套上要寻找的数字,如果这个数是要寻找的数字的因数,就用一个变量自增。检测结束后检测因数和要寻找的数字是否相等,返回真或假。
def find(find_number):#新建函数find查找因数并进行判断
he=0#初始化变量
for i in range(1,find_number):#循环find_number次
if find_number%i==0:#如果i是find_number的因数
he=he+i#赋值
#这时候,he就是find_number所有因数的和了
if he==find_number:#比较
return True
else:
return False
最关键的部分已经做好了,补全代码你可以自己试试~
补全代码,先询问要检测到哪里,之后while循环或者for+range来计数,调用函数获取信息,十分的简单。
完整程序就是这样:
def find(find_number):#新建函数find查找因数并进行判断
he=0#初始化变量
for i in range(1,find_number):#循环find_number次
if find_number%i==0:#如果i是find_number的因数
he=he+i
#这时候,he就是find_number所有因数的和了
if he==find_number:#比较
return True
else:
return False
a=int(input("输入要检测1到多少位的完全数"))
for i in range(1,a+1):
if find(i):
print(i,"是完全数")
四、版本1.1:数的末尾侦测
从上文我们可以知道,完全数的末尾都是6或者28,这样的话,我们就又能节约一下运行时间了。
有人问了:诶诶诶,怎么知道一个整数的末尾是多少呢?
很简单,变成字符串再截取就行了。
def find(find_number):#新建函数find查找因数并进行判断
he=0#初始化变量
for i in range(1,find_number):#循环find_number次
if find_number%i==0:#如果i是find_number的因数
he=he+i
#这时候,he就是find_number所有因数的和了
if he==find_number:#比较
return True
else:
return False
a=int(input("输入要检测1到多少位的完全数"))
for i in range(1,a+1):
if str(i)[-1]=='6' or str(i)[-1]=='8':
if find(i):
print(i,"是完全数")
这样运行速度直接快了一倍好吧。
五、版本1.2:除以9侦测
完全数除以9都余1,我们也可用这一点来加快运行速度。不过,千万不要忽略“排除6”,再加一个是不是6的侦测。看起来更烦琐了,但是这样做将近能快3倍速度。
def find(find_number):#新建函数find查找因数并进行判断
he=0#初始化变量
for i in range(1,find_number):#循环find_number次
if find_number%i==0:#如果i是find_number的因数
he=he+i
#这时候,he就是find_number所有因数的和了
if he==find_number:#比较
return True
else:
return False
a=int(input("输入要检测1到多少位的完全数"))
for i in range(1,a+1):
if str(i)[-1]=='6' or str(i)[-1]=='8':
if i%9==1 or i==6:
if find(i):
print(i,"是完全数")
六、版本2.0:梅森素数侦测
这是最后的终极方法,就是寻找梅森素数。
首先还是要侦测素数的大循环,if来判断素数是不是梅森素数,是的话就代入公式输出,十分的简单。
在上一个哥德巴 赫猜想的文章里面已经有了素数侦测的函数,这里直接拿过来用,诶嘿。
c,运行太快了,停不住了,诶!
(哔~)
我们再加一个等待时间就好了,有点快了。
from time import sleep
zhishu=[]#储存质数的列表
for i in range(2,10000):#循环检测质数
for j in range(2,i-1):#2到i内的每一个数
if i%j==0:#如果i不是质数
break#退出循环
else:#如果正常结束循环就是i是质数
zhishu.append(i)#zhishu添加i
for shu in zhishu:
if 2**shu-1 in zhishu:
print(2**(shu-1)*(2**shu-1),"是完全数")
sleep(1)
但是这样检测有一个致命的缺点——只能检测10000以内的,因为我们用的是in来判断2**shu-1是不是质数,大于10000就没有了,要是能有一个质数表数据的话,肯定能找他十几个。
来源:https://blog.csdn.net/C_ygxb/article/details/128439029


猜你喜欢
- 最近发现现有框架的通用查询存储过程的性能慢,于是仔细研究了下代码:Alter PROCEDURE [dbo].[AreaSelect]&nb
- 在这之前我们先回顾以前用php导出excel,我直接写成方法在这里:public static function phpExcelList(
- 一、pandas分组1、分组运算过程:split->apply->combine拆分:进行分组的根据应用:每个分组运行的计算规则
- 本文实例为大家分享了vue实现简单全选和反选的具体代码,供大家参考,具体内容如下<!DOCTYPE html><html
- /usr/sbin/groupadd mysql/usr/sbin/useradd -g mysql mysqlunzip mysql-5.
- 问题:1. 访问 ASP 页面时,出现以下错误:Active Server Pages 错误 'ASP 0201'错误无效的
- 一个网站信息结构需要表现给用户看,这样用户才能知道当前是在哪儿,才有可能去猜测某个内容可能会在哪儿。如何表现网站的信息结构给用户呢?用导航。
- 本文首先介绍了Python中的模块的概念,谈到了一个模块往往由多个模块组成,然后通过具体实例,分析了模块重载的相关内容,具体介绍如下。模块是
- MySQL分页分析原理及提高效率PERCONA PERFORMANCE CONFERENCE 2009上,来自雅虎的几位工程师带来了一篇”E
- 又从 James Padolsey 这里得到个好的点子。在实际写脚本过程中可能有段 Javascript 和 HTML 非常相关(比如实例化
- (在lua中通过loadfile, setfenv实现)python当然也可以:cat config.pybar = 10foo=100ca
- 反射的优点它的核心本质其实就是基于字符串的事件驱动,通过字符串的形式去操作对象的属性或者方法一个概念被提出来,就是要明白它的优点有哪些,这样
- 一、Mysql SQL Mode简介通常来说MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式。这样
- 自己的小Python项目好几天没有写了,今天打开PyCharm准备继续写,突然发现之前的激活码被取消不能用了,本来激情满满的准备干活啦!之前
- 导语嘿!大家好,我是木木子!今天给大家带来一个好玩儿的Python小程序,希望大家喜欢,记得点点关注啦~有没有什么内容形式,比小视频更小,比
- 如下所示: out = subprocess.getstatusoutput('adb shell pm
- import urllib.parse,os.path,time,sys,re,urllib.requestfrom http.client
- Oracle分页查询的实例详解1.Oracle分页查询:SELECT * FROM ( SELECT A.*, ROWNUM RN FROM
- 前言Helium工具是对Selenium的封装,将Selenium工具的使用变得更加简单。Selenium虽然好,但是在它的使用过程中元素的
- common中存放的是整个项目中公共使用的封装方法从工程目录上可以看到区分datas中专门存放测试数据(yml文件)cases中专门集中存放