哥德巴赫猜測驗證

一、問題描述算法

  大於等於6以上的偶數總有 = 2個質數之和;數組

  例:12 = 3 + 9 Xide

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

基本分析spa

wKiom1isgKbwg7i2AAAgjxdIpdI917.png-wh_50


二、基礎算法代碼實現blog

#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");
    }
}


結果截圖內存

wKiom1ishv3SPSfoAAA***HkXac636.png-wh_50

算法分析:get

  基礎算法,的真正耗時的主要運算在"質數判斷"上,無需計算,算法速度將大大加快。
it


三、中級算法io

  (1)、思路:先把9位之內的全部質數都找出來,是質數的爲0,不是質數的爲1,判斷是否爲質數查表便可;

篩選法:以數組下標爲數值自己,而相關元素的值爲0或1,0:是質數,1:非質數;

算法模型:

wKiom1is9CLztqJYAAAmZajVYe0243.png-wh_50

  (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)、結果截圖

wKioL1is9RGRN8S3AAA1jbkPvkI379.png-wh_50

  算法分析:

  由於用的輔助空間是char類型的,而只需存儲0/1,全部太浪費內存空間,而且都是* 、/這類,運算速度比較慢


四、極端算法

  (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");
    }
}

結果截圖:

wKioL1itH5-xaT0DAAAhuX1eMj4541.png-wh_50

算法分析:

  關鍵在質數判斷上面進行的算法的極簡優化,由char-->位的簡化,和位運算的執行速率極高;

相關文章
相關標籤/搜索