目錄所謂篩法是一種思想,就像名字一樣,篩去多餘的,篩去錯誤的。多數情況用陣列標記,複雜度看起來很大,但**跑起來確是越跑越快。
把n以內素數全找出來(n<=100000)大家一定想得到第一種方法,暴力,遍歷。
//暴力
#include#includeint isprime(int n)
return 1;
}int main()
return 0;
}
注:用n=sqrt(n),可以增加運算速度,畢竟sqrt也是很慢的。但是這種方法還是很慢,慢在每次都要判斷。
接下來看篩法
所謂素數,就是不能表示為比它更小的數的乘積。
且,任何乙個素數的倍數一定不是素數。
我們先定義乙個陣列來存100000以內數是否的素數,下標表示數,陣列的值1表示是素數,0表示不是素數。
我們可以換個角度思考,要找素數,其實只要把不是素數的排除就可以了。
接下來我們可以構造一張表。初始0
1234
5678
91000
0000
0000
0我們可以把2的倍數變成1,因為任何乙個素數的倍數一定不是素數。01
2345
6789
10001
0101
0101
然後是3的倍數01
2345
6789
10001
0101
0111
。。。。。。
照這樣就可以得到一張素數表了,哈哈。
看**。
//篩選法
#include#includeint a[100001];
int main()
} printf("2");
for(int i = 3; i <= n; i++)
}reutrn 0;
}
這個**還可以改進。
第一,我們不用篩到n,其實只要和暴力方法一樣,篩到sqrt(n)就可以了。
第二,我們篩3時多篩了3*2,篩5時多篩了5*2,5*3,5*4。只要從i*i開始篩就可以了。
//篩選法優化一
#include#includeint a[100001];
int main()
} printf("2");
for(int i = 3; i <= n; i++)
}reutrn 0;
}
其實還可以改進,這裡我就不說了。
把2的情況用位運算,再把j+=i變為j+=2*i
看起來時間複雜度為o(n*n),其實在處理很多資料時,它是越跑越快,相當於o(6*n)。
1,如果要判斷素數個數,可以用乙個陣列存一下有幾個,結合篩法,也是很方便的。
2,如果要判斷50-100有幾個素數,只要(100的素數個數-50的素數個數),再判斷一下100與50的素數情況。
3,這種篩法叫埃拉託斯特尼篩法。
素數篩法(素數篩 線性篩)
求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...
篩法求素數 線性篩法求素數
2021年更新版 篩法求素數 線性篩法求素數 要理解篩法求素數首先要知道乙個定理,整數唯一分解定理 任意大於等於2的正整數都有且只有一種方式寫出其質因子的乘積表示式。a p1p2p3p4 pn pi是素數且pi pj eg 2 2 4 22 12 223 36 2233 也就是說任意乙個合數都能分成...
素數篩法(埃氏篩,線性篩)
時間複雜度o nloglogn void prime int b prime i 1則是合數 原理很簡單,所有合數可以表示為乙個質數跟另乙個數的積,列舉每個已知素數的倍數就能標記完。但很明顯,這樣做會有重複。比如12 3 4 2 6,在2這個素數進行倍數標記時會標記,在3這個素數進行倍數標記時同樣會...