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

2022-08-28 17:00:24 字數 1537 閱讀 8336

目錄所謂篩法是一種思想,就像名字一樣,篩去多餘的,篩去錯誤的。多數情況用陣列標記,複雜度看起來很大,但**跑起來確是越跑越快。

把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這個素數進行倍數標記時同樣會...