【C语言】验证哥德巴赫猜想


问题来源

这是学校的一个作业,原题如下

U5T2

题目先给出了哥德巴赫猜想的背景知识(我还真不知道)

2000以内的正偶数都能分解成两个质数(素数)之和

题目要求

下面来梳理一下题目的要求:

  • 输出样式为a=b+c,使用%4d=%4d+%4d输出
  • 每行输出4个,每行最后一个输出无空格
  • 每个偶数只需要一个结果即可(后续较大的偶数有很多种解)

弄懂了题目要求,下面就来一步一步写代码


如何判断素数?

在上篇博客里面提到了如何判断素数==>【链接】,这里不再赘述

我们需要搞定的是判断是那两个素数b、c相加等于我们需要的那个数a

因为需要多次判断,这里我们使用自定义函数

int SuShu(int a)
{
	if (a == 1)
	{
		return 0;//1不是素数
	}
	int j = 0;
	for(j = 2; j <=sqrt(a); j++)
	{
		if (a % j == 0)
		{
			return 0;
		}
	}
	return 1;
}

为什么是return1和0呢?

因为在写这段代码的时候,我本来是想判断之后返回一个素数,但是这个方法效率太低

而且写到后面我自己都不会写了,遂放弃。


主函数

最终实现形式:n=a+(n-a)

在自定以函数里面返回的值是1和0

主函数里面就需要内容来接收

if (SuShu(a) && SuShu(n - a))//判断a和n-a是否都是素数

同时我们需要完成打印4行换一行,以及每行最后一个不能有空格的要求

这时候直接在printf语句里面加空格已经不够了

需要用到判断语句,判断已经打印了几个等式

if (SuShu(a) && SuShu(n - a))
{
	printf("%4d=%4d+%4d", n, a, n - a);
	count++;//每打印一次就++一次
	if (count % 4 == 0)
	{  //打印4次后打印一个换行符
	printf("\n");
	}
	else
	{  //不够4次,需要打印空格
	printf(" ");
	}
}

素数判断的部分我们已经写完了

接下来要写的是一个for循环,让n从4开始一直+到2000

另外,同【如何判断素数】博客中的开平方法一样

在验证哥德巴赫猜想的时候,若a=b+c,b和c中肯定有一个数小于或等于a/2

在写a的for循环的时候,我们可以让判断条件a<=n/2,而不是a<n

	for (n = 4; n <= 2000; n+=2)
	{
		for (int a = 2; a <= n/2 ; a++)
		{  //在之前我们并没有定义a,需要在for循环里加上int
			if (SuShu(a) && SuShu(n - a))
			{
				printf("%4d=%4d+%4d", n, a, n - a);
				count++;
				if (count % 4 == 0)
				{
					printf("\n");
				}
				else
				{
					printf(" ");
				}
			}
		}
		
	}

到这里,我们的主函数也完成啦!

完整代码+效果演示

#include <stdio.h>
#include <math.h> 

int SuShu(int a)
{
	if (a == 1)
	{
		return 0;
	}
	int j = 0;
	for(j = 2; j <=sqrt(a); j++)
	{
		if (a % j == 0)
		{
			return 0;
		}
	}
	return 1;
}
//验证哥德巴赫猜想,输出4到2000的偶数
//每个偶数的结果只输出一次
int main()
{
	int n = 0;
	int count = 0;
	for (n = 4; n <= 2000; n+=2)
	{
		for (int a = 2; a <= n/2 ; a++)
		{
			if (SuShu(a) && SuShu(n - a))
			{
				printf("%4d=%4d+%4d", n, a, n - a);
				count++;
				if (count % 4 == 0)
				{
					printf("\n");
				}
				else
				{
					printf(" ");
				}
				break; //只打印一种情况
			}
		}
		
	}
	return 0;
}

细心的你肯定注意到,在main函数中判断素数的语句里多了一个break,它的作用是什么呢?

如果没有break,结果如下:

代码会将符合条件的素数相加全部打印出来

这显然不符合每个偶数的结果只输出一次的要求

1

但在加了break这个断点之后

代码的结果就和题目要求的一样了

2


写代码中的误解

在最终提交代码的时候,我的代码格式出错了

原因是我在printf语句里面加多了两个空格,如下:

printf("%4d= %4d+ %4d", n, a, n - a);

为什么我会想当然的多加两个空格呢?

因为题目所给的输出样例,让我误以为=和+之间都有两个空格

image-20211030155057778

实际上这里并没有空格,它的“空格”是printf中的%4d造成的

代码给这里留了4个数字的位置,但是大多都只有一个数字和两个数字

于是它们前面就会有3或者2个留给数字的空,让我误以为这里有空格

基础不牢,地动山摇!


总结

通过这道题,我复习了循环和自定义函数的写法,也获得了哥德巴赫猜想的新知识

多刷刷题总是好的

希望这篇博客对你有帮助!

根据提供的引用内容,以下是使用C语言验证哥德巴赫猜想的基础版方法: 1. 首先,我们需要生成一个素数表。素数表是一个包含一定范围内所有素数的列表。可以使用筛选法来生成素数表。 2. 接下来,我们使用基础版的方法来验证哥德巴赫猜想哥德巴赫猜想指出,每个大于2的偶数都可以表示为两个素数之和。 3. 我们遍历素数表中的每个素数p,然后在素数表中查找是否存在另一个素数q,使得p+q等于给定的偶数n。 4. 如果找到了满足条件的素数p和q,则可以得出结论,该偶数n可以表示为p+q。 5. 如果遍历完素数表仍然没有找到满足条件的素数p和q,则可以得出结论,该偶数n不能表示为两个素数之和。 以下是C语言代码示例: ```c #include <stdio.h> // 判断一个数是否为素数 int isPrime(int num) { if (num <= 1) { return 0; } for (int i = 2; i * i <= num; i++) { if (num % i == 0) { return 0; } } return 1; } // 生成素数表 void generatePrimeTable(int maxNum, int primeTable[]) { int count = 0; for (int i = 2; i <= maxNum; i++) { if (isPrime(i)) { primeTable[count++] = i; } } } // 验证哥德巴赫猜想(基础版) void verifyGoldbachConjecture(int evenNum, int primeTable[]) { for (int i = 0; primeTable[i] <= evenNum / 2; i++) { int p = primeTable[i]; int q = evenNum - p; if (isPrime(q)) { printf("%d = %d + %d\n", evenNum, p, q); return; } } printf("Cannot find two primes that sum up to %d\n", evenNum); } int main() { int maxNum = 1000; // 生成素数表的最大范围 int primeTable[maxNum]; generatePrimeTable(maxNum, primeTable); int evenNum = 20; // 需要验证的偶数 verifyGoldbachConjecture(evenNum, primeTable); return 0; } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

慕雪华年

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值