WV 51 素數篩選優化

2021-06-28 16:14:14 字數 2534 閱讀 1837

合數過濾篩選法

演算法描述:我們知道,素數

n不能被

2~(n-1)

間的任何數整除;反過來看,只要能被

2~(n-1)

間的任何數整除的

n,都不是素數。所以我們可以採用乙個簡單的排除法:就是對

n以內的所有數,只要逐個去除值為

2~(n-1)

的倍數的數,剩下的就是素數。

c

語言實現

// 合數過濾篩選法 ver1 

// 引數:n 求解n以內(包括n)的素數

// 返回值:n以內素數個數

int compositenumfilterv1(int n)

// 寫程式要注意排版和留空,方便閱讀,也可減少出錯機率

// 以2~(n-1)為因子過濾合數

for (i=2; i < n; i++) }

// 統計素數個數

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

// 因輸出費時,且和演算法核心相關不大,故略

// 釋放記憶體,別忘了傳說中的記憶體洩漏

free(flag);

return count;

}

在上文給出的

main

函式中以不同引數呼叫

compositenumfilterv1

函式,得到執行結果如下:

[100000]

以內素數個數:

9592, 

計算用時:

15毫秒

[1000000]

以內素數個數:

78498, 

計算用時:

125毫秒

[5000000]

以內素數個數:

348513, 

計算用時:

2578

毫秒[10000000]

以內素數個數:

664579, 

計算用時:

6281毫秒

注:因程式是非獨占性執行的,所以時間不是完全精確的,但基本能反映實情

顯然,比上文中的試除法要快,而且誰都可以看到上例是乙個未經優化的粗陋版本,好多地方是三藏故意採用比較低效做法,為了與後文的優化版比較,凸顯優化之重要,也為了初學者記住別採用類似低效做法,下面我們開始優化之旅

優化分析

上面compositenumfilterv1

函式存在的問題有: 1.

在外層迴圈,需要一直執行到

n-1嗎?不要,因為

n/2~n-1

間的數顯然不能整除n

2.在內層迴圈中重複使用

i*j顯然是低效的,考慮到計算機中加減運算速度比乘除快可以考慮變乘法為加法 3.

在迴圈修改

flag

過程中,其實有很多數會被重複計算若干次,比如

6=2*3=3*2

,會被重複置

0,類似操作很多,所以我們得設法避免或減少

flag

重複置0

據上述分析,我們可將程式優化如下:

// 合數過濾篩選法 ver2

// 引數:n 求解n以內(包括n)的素數

// 返回值:n以內素數個數

int compositenumfilterv2(int n)

flag[2] = 1;

flag[3] = 1;

flag[5] = 1;

flag[7] = 1;

flag[11] = 1;

flag[13] = 1;

// 從17開始filter,因為2,3,5,7,11,13的倍數早被kill了

// 到n/13止的,哈哈,少了好多吧

int stop = n/13;

for (i=17; i <= stop; i++)

}// 統計素數個數

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

// 因輸出費時,且和演算法核心相關不大,故略

// 釋放記憶體,別忘了傳說中的記憶體洩漏

free(flag);

return count;

}

再看compositenumfilterv3

執行結果:

[1000000]

以內素數個數:

78498, 

計算用時:

15毫秒

[5000000]

以內素數個數:

348513, 

計算用時:

203毫秒

[10000000]

以內素數個數:

664579, 

計算用時:

515毫秒

[100000000]

以內素數個數:

5761455, 

計算用時:

6421毫秒

再次優化後速度提公升了又一倍左右

素數篩法(素數篩 線性篩)

求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...

素數判定,素數篩

這些零碎的知識點每個都學過n次了,但隔一段時間就會忘,記錄下來 素數定義 只能被自身和1整除的大於1的正整數 通過這個定義,我們就可以得出判斷素數的 這裡用到了cmath中的sqrt函式,其原型為double sqrt double 所以在取上界的時候,為了避免double帶來的精度丟失,寧可多列舉...

素數與素數篩

素數篩法 線性篩法 啊,耳熟能詳。素數又稱質數,乙個大於1 11的自然數,除了1 11和它本身外,不能被其他自然數整除,換句話說就是該數除了1 11和它本身以外不再有其他的因數 否則稱為合數。啊!1 11不是素數啊 啊,也耳熟能詳了,暴力列舉一下除1 11和本身的自然數是否會被整除。bool is ...