鱼C论坛

 找回密码
 立即注册
查看: 5791|回复: 17

[技术交流] 19 - 素数的收官:哥德巴赫猜想

[复制链接]
发表于 2021-8-4 17:40:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 不二如是 于 2022-6-27 18:10 编辑

在线讲解:



1_-td1mfxKjc4Q48zPTctdYA.png

经过前面 3 讲关于素数的讨论,这是我们素数的收官之战:哥德巴赫猜想

相信童鞋们或多或少都听过“哥德巴赫猜想”这个东东,这里小师妹就简单再啰嗦一小下:

哥德巴赫猜想(Goldbach's conjecture)是数论中存在最久的未解问:
goldbachgoldbach-1.png
用现代的数学语言,哥德巴赫猜想可以陈述为:任一大于 2 的偶数,都可表示成两个素数之和。

这个猜想与当时欧洲数论学家讨论的整数分拆问题有一定联系。

整数分拆问题是一类讨论“是否能将整数分拆为某些拥有特定性质的数的和”的问题。

比如能否将所有整数都分拆为若干个完全平方数之和,或者若干个完全立方数的和等。

而将一个给定的偶数分拆成两个素数之和,则被称之为此数的哥德巴赫分拆。

例如:

  1. 4 = 2 + 2
  2. 6 = 3 + 3
  3. 8 = 3 + 5
  4. 10 = 3 + 7 = 5 + 5
  5. 12 = 5 + 7
  6. 14 = 3 + 11 = 7 + 7
复制代码

而我们这次要做的就是求解:

2333 以内的不小于 4 的正偶数都能够分解为两个素数之和。

为了验证歌德巴赫猜想对 2333 以内的正偶数都是成立的,要将整数分解为两部分,然后判断分解出的两个整数是否均为素数。

若是,则满足题意,否则应重新进行分解和判断。

针对该问题,我们可以给定如下的输入和输出限定。

输入时:

每行输入一组数据,即 2333 以内的正偶数n ,一直输入到文件结束符为止。

输出时:

输出 n 能被分解成的素数 a 和 b。如果不止一组解,则输出其中 a 最小的那组解。

当然,肯定要根据实际的需要规定不同的输入和输出形式。

例如输入:

4
6
8
10
12

输出:

2 2
3 3
3 5
3 7
5 7

通过上面的分析,我们需要两个自定义函数,来实现两个功能:

  • 判断素数
  • 验证猜想

判断素数的我们已经用过很多次啦,就不废话了,prime() 拿来直接调用:

  1. def prime(n):
  2.     m = math.sqrt(n)
  3.     i = 2
  4.     while i <= m:
  5.         if n % i == 0:
  6.             return 0
  7.         i += 1
  8.     return 1
复制代码

重点在下面的验证猜想。

由于我们已经对输出做了限定,即当输出结果时,如果有多组解,则输出 a 最小的那组解。


为了防止有些鱼油故意输入奇数,我们用一个小判断来告诉他们按要求输入:

  1. if (n%2) != 0:
  2.         print("这是奇数噢,请输入大于4的正偶数")
  3.         return
复制代码

然后我们对每个读入的数据 n,a 必然小于或等于 n//2,因此,定义循环变量 i。

使其从 2~n//2 进行循环,每次循环都判断 prime(i) 和 prime(n-i) 是否为 1。

如果 prime(i) 和 prime(n-i) 为 1,此时 i 和 n-i 都为素数,又由于 i 是从 2~n/2 按由小到大的顺序来迭代的。

因此(i,n-i)是我们求出的一组解,且该组解必然是所有可能解中 a 值最小的。

还需要注意的是,由于除了 2 以外的偶数不可能是素数。

因此,i 值的可能取值只能是 2 和所有的奇数。

那我们就将上面的函数取名为 guess() ,功能就是验证传入的参数 n 是否满足哥德巴赫猜想。

代码其实不难,一个 while 循环搞定:

游客,如果您要查看本帖隐藏内容请回复

既然是验证,就不能像之前一样执行一次就结束,需要反复执行输出结果。

主框架还是用 while 循环,每输入一个数据就处理一次,直到人为结束程序或输入非法数据而终止输入:

  1. if __name__ == "__main__":
  2.     while True:
  3.         print("请输入一个不小于4的正偶数:")
  4.         n = int(input())
  5.         guess(n)
复制代码

if __name__ == '__main__' 的意思就是当 .py 文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行。

好啦,这里执行下看结果:

2021-08-09_19-07-19.jpg

源码: 19.py.zip (949 Bytes, 下载次数: 11, 售价: 8 鱼币)

核心代码都有了,完整代码留给你们当作业!

好了,下课!

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-4 18:04:37 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-5 12:33:46 | 显示全部楼层
6666666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-5 19:30:22 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-6 09:47:22 | 显示全部楼层
666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 11:03:31 | 显示全部楼层
xueyixia
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-11 15:02:19 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 16:24:12 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 16:43:42 | 显示全部楼层
mod
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-16 09:36:02 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-17 21:08:11 | 显示全部楼层
·1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-9 17:47:56 | 显示全部楼层
把素数搞懂了一起就好办了!
  1. even = int(input('请输入一个不小于4的正偶数:'))
  2. for i in range(2,even):
  3.     for n in range(2,i):
  4.         if  i % n == 0:
  5.             break
  6.     else:
  7.         j = even - i
  8.         for n in range(2,j):
  9.             if j % n ==0:
  10.                 break
  11.         else:
  12.             print("分解结果:",i,j)
  13.             break
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-8 16:39:04 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-4 22:07:33 | 显示全部楼层
好耶
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-5-9 16:12:13 | 显示全部楼层
# 题干
# 将一个给定的正偶数分拆成两个素数之和,则被称之为此数的哥德巴赫分拆。
# 循环打印直至非法输入

def judgeprime(index):
    storage = []
    for i in range(2, index):
        if index%i == 0:
            storage.append(i)
            break
    if len(storage) == 0:
        return True
    else:
        return False

while True:
    try:
        inputnumber = int(input('请输入一个取值在[4, 2333]区间的正偶数:'))
    except ValueError:
        print('非法输入!已结束程序!')
        break
    except KeyboardInterrupt:
        print('非法输入!已结束程序!')
        break
    else:
        if (inputnumber < 4) or (inputnumber % 2 == 1):
            print('非法输入!已结束程序!')
            break
        else:
            for left in range(2, inputnumber-1):
                right = inputnumber - left
                if left <= right:
                    if judgeprime(left) and judgeprime(right):
                        print('%d = %d + %d' % (inputnumber, left, right))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-2 15:54:24 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-26 14:26:37 | 显示全部楼层
搜噶寺内
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-6 21:52:50 | 显示全部楼层
沙发
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-1 08:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表