日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

哥德巴赫猜想的验证

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哥德巴赫猜想的验证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、什么是哥德巴赫猜想

?????? 哥德巴赫猜想:任意大于6的偶數,都可以分解為兩個質數的和。

二、哥德巴赫猜想的驗證

方法一:

#include <stdio.h> #include <time.h>#include "mec.h"void checkGoldBech(int num); boolean canResolve(int num); boolean isPrime(int num);boolean isPrime(int num){int n;for(n = 2;n < num && num % n;n ++ ){;}return n >= num; }boolean canResolve(int num){int j;for(j = 3;j <= num/2 ;j += 2){if(isPrime(j) && isPrime(num - j)){ // printf("%d = %d + %d\n",num ,j ,num - j);return TRUE;}}return FALSE; }void checkGoldBech(int num){int i;for(i = 6;i <= num; i += 2){if(!canResolve(i)){printf("哥德巴赫猜想是錯誤的!!\n");return;}}printf("哥德巴赫猜想是正確的!!!\n"); }int main(){int num;long startTime;long endTime;printf("請輸入要查詢的范圍:");scanf("%d",&num);startTime = clock();checkGoldBech(num);endTime = clock();endTime -= startTime;printf("耗時:%d.%03d\n",endTime / 1000,endTime % 1000);return 0; }

上述的方法,在判斷一個數是否為質數的函數(isPrime)中,使用了大家最容易想到的操作:即n從0開始循環與num相與,直至n循環到num-1。而恰恰是這個函數最為耗時,使得程序的效率極低。當運行程序時,驗證的位數較大(8位數或者更大)時,耗時極多。因此,我們有必要對此函數進行優化!!

方法二:

boolean isPrime(int num){int n;int midleNum;if(n == 2){return TRUE;}if(num % 2 == 0 && num >2){return FALSE;}midleNum = (int)(sqrt(num) + 1);for(n = 3;n <= midleNum && num % n;n += 2 ){;}return n > midleNum; }

方法二在方法一的基礎上,更優化了一步。當傳入一個num時,先判斷是否為2,若是2(質數),直接返回TRUE;若是其它數,先排除所有大于2偶數,然后再對奇數進行判斷。在這里,循環只需要進行到根號下num即可。理由如下:若傳入的數為10000,10000/2 = 5000,則從5001到9999之間,不會存在一個數可以被10000整除;再思考,10000/3 = 3333.33,那么,3333到4999之間就沒必要考慮了;10000 / 4 = 2500,那么,2501到 3332之間就不用考慮了...... 并且,如果我們檢測過了2,那就沒有必要再檢測5000了。綜上,對于10000,我們只需要從2檢測到100就夠了,也就是檢測到根號10000就夠了,

方法三:

?????? 程序再優化:不再對2至根號num的數進行意義判斷,而是直接“得知”這個數是否為質數,這樣就可以極大地提高算法的速度!

?????? 若要求驗證的范圍為num,則,將[2,num)中所有的質數全部找到,并把它們存放在一個擁有num個元素的數組中。假設index在[2,num)之間,以index為下標,array[index]中的值有兩種:0或1,分別代表質數和非質數。

?????? 這樣一來,判斷一個數是否為質數,只需要判斷array[index]中的值即可!

boolean *primePool; //質數池(數組)void screenPrime(int count){int prime = 2;int i;int lastNum;int index;for(index = 4;index < count ;index += 2){primePool[index] = 1;}lastNum = (int(sqrt(count)) + 1);for(index = 3;index <= lastNum ; index += 2){if(primePool[index] == 0){for(i = index * index;i < count;i += index){primePool[i] = 1;}}}} //篩選質數并設置0/1boolean isPrime(int num){return !primePool[num]; //判斷數組元素中的值 }

在上面的篩選質數函數(screenPrime)中,我們對質數的判斷又進行了優化。這里要提出一種方法:篩選法

以上的解釋摘自百度百科。

在這里對篩選法再進行一些解釋,若一個數m是質數,則2*m已經被2篩去了,3*m已經被3篩去了...... 因此從m*m開始篩選即可!相信上述定義對照來看代碼不難理解。

方法四:

方法三仍有優化的地方,它最大的消耗是內存空間!因為需要申請一個長度為num的數組!雖然我們已經使用了boolean 類型,但還是耗費了很多空間。那么,我們是否可以用一個二進制位來表示一個數是否為質數呢?答案是可以。

通過上圖我們可以清晰地看到從數組的第一個元素開始,依次保存0~num的質數性(每個元素保存八個數字的質數性)。這樣一來,就大大地節省了內存空間。

下面,我們只需要宏定義三個量,分別進行“取位”、“清位”、“置位”的操作即可。

#define SETB(value,index) (value |= 1 << ((index)^7)) //置位 #define CLRB(value,index) (value &= ~(1 << ((index)^7))) //清位 #define GETB(value,index) (((value) & (1 <<((index) ^ 7))) != 0) //取位

有了這三個宏定義,我們進一步的代碼優化就可以完成了:

void screenPrime(int count){int prime = 2;unsigned int i;unsigned int j;int lastNum;int index;for(index = 4;index < count ;index += 2){SETB(primePool[index >> 3],index & 7);}lastNum = (int(sqrt(count)) + 1);for(i = 3;i <= lastNum ; i += 2){if(!GETB(primePool[(unsigned int) i >> 3],i & 7)){for(j = i * i;j < count;j += i){SETB(primePool[j >> 3],j & 7);}}}}

??? 在這種方法中,我們使用了位運算,即對“位”來進行操作。這是計算及內部極其高效的一種手段,因而也極大地提高了程序的效率!!

以上說法若有不周之處,還請各位指點。

總結

以上是生活随笔為你收集整理的哥德巴赫猜想的验证的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。