哥德巴赫猜想验证

1、问题描述

大于等于6以上的偶数总有 = 2个质数之和;

例:12 = 3 + 9 X

12 = 5 + 7 V (哥德巴赫猜想成立);

基本分析

2、基础算法代码实现

#include<stdio.h>

typedef unsigned char boolean;

#define TRUE    1
#define    FALSE    0

boolean isPrime(int n);
boolean Gguess(int userNumber);

boolean Gguess(int userNumber){
    int num;
    int i;
    int flag = TRUE;

    for(num = 6; TRUE == flag && num < userNumber; num += 2){ //从6开始---userNumber的所有数字进行哥德巴赫猜想
        flag = FALSE;
        for(i = 3; i < num && FALSE == flag; i += 2){
            if(isPrime(i) && isPrime(num-i)){
                flag = TRUE;
                printf("%d = %d + %d\n", num, i, num-i);
            }
        }
    }
}

boolean isPrime(int n){
    int i;

    for(i = 2; i<n && n%i; i++)
        ;

    return i >= n;
}

void main(void){
    int num;

    printf("请输入一个边界数: ");
    scanf("%d", &num);

    if(FALSE == Gguess(num)){
        printf("哥德巴赫猜想失败\n");
    }else{
        printf("哥德巴赫猜想成功了\n");
    }
}

结果截图

算法分析:

基础算法,的真正耗时的主要运算在"质数判断"上,无需计算,算法速度将大大加快。

3、中级算法

(1)、思路:先把9位以内的所有质数都找出来,是质数的为0,不是质数的为1,判断是否为质数查表即可;

筛选法:以数组下标为数值本身,而相关元素的值为0或1,0:是质数,1:非质数;

算法模型:

(2)、判断是否为质数的高效代码

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

void findPrime(int number, char **p);

void findPrime(int number, char **p){
    int len = (int)(sqrt(number));
    int i;
    int j;
    char *pool;

    pool = (char *)calloc(sizeof(char), number);
    for(i = 2; i < len; i++){  //从2判断到根号number的长度即可
        if(pool[i] == 0){  
            for(j = i*i; j < number; j += i){  //前面的都重复的判断过了
                pool[j] = 1; //非质数标记为1
            }    
        }
    }

    *p = pool;
}

void main(void){
    int number;
    char *p = NULL;
    int i; 

    printf("请输入多少位内的质数: ");
    scanf("%d", &number);

    findPrime(number, &p);

    for(i = 3; i < number; i++){
        if(p[i] == 0){
            printf("%d ", i);
        }
    }
    printf("\n");

    free(p);
}

(3)、结果截图

算法分析:

因为用的辅助空间是char类型的,而只需存储0/1,所有太浪费内存空间,并且都是* 、/这类,运算速度比较慢

4、极端算法

(1)、位运算的判断质数

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

//位运算计算的效率更快
#define        SET_BIT(byte, i)    (byte |= 1 << (7 ^ (i)))  //设置这个字节的指定位为1
#define        CLR_BIT(byte, i)    (byte &= ~(1 << (7 ^ (i)))) //设置这个字节的指定位为0
#define        GET_BIT(byte, i)    !!((byte) & (1 << (7^(i))))  //得到这个字节的指定位

// num >> 3  数组下标
// num & 7 <===> num % 8  
void findPrime(int number, char **p);

void findPrime(int number, char **p){
    int len = (int)(sqrt(number));
    int i;
    int j;
    char *pool;

    pool = (char *)calloc(sizeof(char), (number+7)>>3);
    for(i = 2; i < len; i++){  //从2判断到根号number的长度即可
        if(GET_BIT(pool[i >> 3], i & 7) == 0){  
            for(j = i*i; j < number; j += i){  //前面的都重复的判断过了
                SET_BIT(pool[j >> 3], j & 7);//非质数标记为1
            }    
        }
    }

    *p = pool;
}

void main(void){
    int number;
    char *p = NULL;
    int i; 

    printf("请输入多少位内的质数: ");
    scanf("%d", &number);

    findPrime(number, &p);

    for(i = 3; i < number; i++){
        if(GET_BIT(p[i >> 3], i & 7) == 0){
            printf("%d ", i);
        }
    }
    printf("\n");

    free(p);
}

(2)、哥德巴赫猜想的完整算法

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

typedef unsigned char boolean;

#define    TRUE    1
#define FALSE    0

//位运算计算的效率更快
#define        SET_BIT(byte, i)    (byte |= 1 << (7 ^ (i)))  //设置这个字节的指定位为1
#define        CLR_BIT(byte, i)    (byte &= ~(1 << (7 ^ (i)))) //设置这个字节的指定位为0
#define        GET_BIT(byte, i)    !!((byte) & (1 << (7^(i))))  //得到这个字节的指定位

// num >> 3  数组下标
// num & 7 <===> num % 8  
void findPrime(int number, char **p);
boolean isPrime(int num, char *p);
boolean Gguess(int userNumber, char *p);

boolean Gguess(int userNumber, char *p){
    int num;
    int i;
    int flag = TRUE;

    for(num = 6; TRUE == flag && num < userNumber; num += 2){ //从6开始---userNumber的所有数字进行哥德巴赫猜想
        flag = FALSE;
        for(i = 3; i < num && FALSE == flag; i += 2){
            if(isPrime(i, p) && isPrime(num-i, p)){
                flag = TRUE;
                printf("%d = %d + %d\n", num, i, num-i);
            }
        }
    }

    return flag;
}

boolean isPrime(int num, char *p){
    return GET_BIT(p[num >> 3], num & 7) == 0;  //0:表示为质数;
}

void findPrime(int number, char **p){
    int len = (int)(sqrt(number));
    int i;
    int j;
    char *pool;

    pool = (char *)calloc(sizeof(char), (number+7)>>3);
    for(i = 2; i < len; i++){  //从2判断到根号number的长度即可
        if(GET_BIT(pool[i >> 3], i & 7) == 0){  
            for(j = i*i; j < number; j += i){  //前面的都重复的判断过了
                SET_BIT(pool[j >> 3], j & 7);//非质数标记为1
            }    
        }
    }

    *p = pool;
}

void main(void){
    int num;
    char *p;

    printf("请输入一个边界数: ");
    scanf("%d", &num);

    findPrime(num, &p);
    if(FALSE == Gguess(num, p)){
        printf("哥德巴赫猜想失败\n");
    }else{
        printf("哥德巴赫猜想成功了\n");
    }
}

结果截图:

算法分析:

关键在质数判断上面进行的算法的极简优化,由char-->位的简化,和位运算的执行速率极高;

时间: 2024-10-22 12:17:56

哥德巴赫猜想验证的相关文章

循环-04. 验证“哥德巴赫猜想”

循环-04. 验证“哥德巴赫猜想”(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 徐镜春(浙江大学) 数学领域著名的“哥德巴赫猜想”的大致意思是:任何一个大于2的偶数总能表示为两个素数之和.比如:24=5+19,其中5和19都是素数.本实验的任务是设计一个程序,验证20亿以内的偶数都可以分解成两个素数之和. 输入格式: 输入在一行中给出一个(2, 2 000 000 000]范围内的偶数N. 输出格式: 在一行中按照格式

Python验证哥德巴赫猜想

今天看到百度知道有人问如何验证1000以内的数符合哥德巴赫猜想,就写了一个 感觉超过10000时有点慢啊,和java比起来效率差了点,希望高手能给优化下 #!/usr/bin/env python __author__ = '淮南霏霏' """ 脚本编写环境python 3.4.2 哥德巴赫猜想 简单验证 """ import math class Goldbach: """ 哥德巴赫猜想:任一大于2的偶数都可写成两

验证哥德巴赫猜想,每个大于等于4的偶数都可以表示成2个素数之和

验证哥德巴赫猜想,每个大于等于4的偶数都可以表示成2个素数之和. 1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 int isou(int num)//1代表偶数,0代表奇数 7 { 8 if (num % 2 == 0) 9 { 10 return 1; 11 } 12 else 13 { 14 return 0; 15 } 16 } 17 18 int sushu(

循环-04. 验证“哥德巴赫猜想”(20)

1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 bool isPrime(long n){ 5 int i; 6 for(i=2;i<=sqrt(n);++i) 7 if(n%i==0) 8 break; 9 if(n>1&&i>sqrt(n)) 10 return true; 11 else 12 return false; 13 } 14 int main(){ 1

编程验证哥德巴赫猜想

1.什么是哥德巴赫猜想 在1742年给欧拉的信中哥德巴赫提出了以下猜想:任一大于2的整数都可写成三个质数之和.因现今数学界已经不使用"1也是素数"这个约定,原初猜想的现代陈述为:任一大于5的整数都可写成三个质数之和.欧拉在回信中也提出另一等价版本,即任一大于2的偶数都可写成两个质数之和.今日常见的猜想陈述为欧拉的版本.把命题"任一充分大的偶数都可以表示成为一个素因子个数不超过a个的数与另一个素因子不超过b个的数之和"记作"a+b".1966年陈景

用C语言来验证哥德巴赫猜想(定义的是int型)

哥德巴赫猜想: 如果任意一个大于6的偶数都可以写成两个素数之和.就将其称为符合哥德巴赫猜想. #include<stdio.h> #include<math.h> /// <summary> /// 判断一个数是否是素数 /// </summary> /// <param name="intNum">要判断的数</param> /// <returns>如果是,返回true,否则,返回false<

40.验证哥德巴赫猜想:一个大于2的偶数总可以分解成两个素数的和

//1.输入一个偶数.判断是否为偶数 //2.若是,求出小于其的所有素数 //3.将它们求和 //4.验证是否满足哥德巴赫猜想 #include<iostream> #include<cmath> using namespace std; int Sushu(int); int main() { int n,k,q; int a[1000]; begin: cout<<"please input an even number(偶数):"<<

【算法】验证哥德巴赫猜想

问题来源 Timus Online Judge 网站上有这么一道题目:1356. Something Easier.这道题目的输入是一组  2 到 109 之间整数,对于每个输入的整数,要求用最少个数的素数的和来表示.这道题目的时间限制是 1 秒. 问题解答 我们知道著名的哥德巴赫猜想是: 任何一个充分大的偶数都可以表示为两个素数之和 于是我们有以下的 C 语言程序(1356.c): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

c语言验证哥德巴赫猜想(从4开始 一个偶数由两个质数之和)

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 5 int isit(int num) 6 { 7 int i; 8 int flag = 1;//表述为素数 9 if(num==2) 10 { 11 return 1; 12 }else if(num==3) 13 { 14 return 1; 15 }else if(num<=1) 16 { 17 return 0; 18 }el