【题目要求】
众所周知,歌德巴赫猜想的证明是一个世界性的数学难题,至尽未能完全解决。我国著名数学家陈景润为歌德巴赫猜想的证明作出过杰出的贡献。
所谓歌德巴赫猜想是说任何一个大于2的偶数都能表示成为两个素数之和。应用计算机工具可以很快地在一定范围内验证歌德巴赫猜想的正确性。请编写一个C程序,验证指定范围内歌德巴赫猜想的正确性,也就是近似证明歌德巴赫猜想(因为不可能用计算机穷举出所有正偶数)。
【题目分析】
可以把问题归结为在指定范围内(例如:1~2000内)验证其中每一个偶数是否满足歌德巴赫猜想的论断,即是否能表示为两个素数之和。如果发现一个偶数不能表示为两个素数之和,即不满足歌德巴赫猜想的论断,则意味着举出了反例,从而可以否定歌德巴赫猜想。
可以应用枚举的方法枚举出指定范围内的每一个偶数,然后判断它是否满足歌德巴赫猜想的论断,一旦发现有不满足歌德巴赫猜想的数据,则可以跳出循环,并做出否定的结论;否则如果集合内的数据都满足歌德巴赫猜想的论断,则可以说明在该指定范围内,歌德巴赫猜想是正确的。
这一过程的伪码算法描述为:
- low ;范围下界
- high ;范围上界
- a恖ow
- repeat:
- if a为偶数并且a>2 then
- if a满足歌德巴赫猜想 then
- 输出一种结论
- else
- 设置标志,跳出循环
- endif
- endif
- a恆+1
- until a>high
- if设置标志 then 歌德巴赫猜想不成立
- else 在[low,high]内歌德巴赫猜想成立
现在问题的核心变为如何验证一个偶数a 是否满足歌德巴赫猜想,即偶数a能否表示为两个素数之和。可以这样考虑这个问题:
一个正偶数a一定可以表示成为a/2种正整数相加的形式。这是因为a=1+(a-1);a=2+(a-2);……;a=a/2-1+a/2+1;a=a/2+a/2;共a/2种。后面还有a/2-1种表示形式与前面a/2-1种表示形式相同,因此可以不考虑。那么,在这a/2种正整数相加的形式中,只要存在一种形式a=i+j,其中i和j均为素数,则就可以断定该偶数a满足歌德巴赫猜想。因此,判断一个大于2的偶数a 是否满足歌德巴赫猜想的伪码算法描述为:
- i?
- repeat:
- if i是素数 and a-i也是素数 then
- 设置标志,跳出循环
- endif
- i恑+1
- until i>a/2
- if 设置标志 then a满足歌德巴赫猜想
- else a不满足歌德巴赫猜想
程序清单5-3
- /*------------------------------ 5-3.c
-------------------------*/- #include <string.h>
- #include <stdio.h>
- int isGoldbach(int a);
- int TestifyGB_Guess(int low,int high);
- int isPrime(int i);
- void main()
- {
- /*验证1~100以内的歌德巴赫猜想*/
- printf("Now testify Goldbach Guess in
the range of 1~100/n/n");- if(TestifyGB_Guess(1,100))
- printf("/nIn the range of 1~100,
Goldbach Guess is right./n");- else printf("/nGoldbach Guess is wrong./n");
- getchar();
- }
- int TestifyGB_Guess (int low,int high)
- {/*在low和high的范围内验证歌德巴赫猜想*/
- int i,j=0;
- int flag=0;
- for(i=low;i<=high;i++)
- if(i%2==0&&i>2)
- if(isGoldbach(i)){ /*偶数i符合歌德巴赫猜想*/
- j++; /*j用来控制输出格式*/
- if(j==5){
- printf("/n");
- j=0;
- }
- }
- else
- {flag=1;break;}
- if(flag==0)
- return 1; /*在low和high
的范围内歌德巴赫猜想正确返回1*/- else
- return 0; /*在low和high
的范围内歌德巴赫猜想不正确返回0*/- }
- int isGoldbach(int a)
- {/*判断偶数a是否符合歌德巴和猜想*/
- int i,flag=0;
- for(i=1;i<=a/2;i++)
- {
- if(isPrime(i)&& isPrime(a-i))
- /*如果i和a-i都为素数,
则符合歌氏猜想*/- {
- flag=1;
- printf("%d=%d+%d ",a,i,a-i);
- break;
- }
- }
- if(flag==1)
- return 1; /*a符合歌德巴赫猜想返回1*/
- else
- return 0; /*a不符合歌德巴赫猜想返回0*/
- }
- int isPrime(int i)
- {/*判断o是否是素数*/
- int n,flag=1;
- if(1==i)flag=0; /*1不是素数,素数都要大于1*/
- for(n=2;n<i;n++)
- if(i%n==0){flag=0;break;}
- /*如果在2~i-1之间i有
其他因子,则i不是素数,flag置0*/- if(flag==1)
- return 1; /*i是素数返回1*/
- else
- return 0; /*i不是素返回0*/
- }
【程序说明】
本程序将歌德巴赫猜想验证的范围规定在100以内。主函数调用3个函数:TestifyGB_Guess()函数有两个参数,分别指定歌德巴赫猜想验证的范围的下界low和上界high,该函数的作用是在[low,high]的范围内验证歌德巴赫猜想的正确性。函数isGoldbach()有一个参数a,它的作用是判断a是否满足歌德巴赫猜想,也就是偶数a是否可表示成两个素数之和。函数isPrime()有一个参数i,判断i是否是素数,这里要注意,严格地讲1不是素数。
程序的运行结果如图5-3所示。
图5-3 程序5-3的运行结果 |