求素數個數

2021-08-13 08:34:35 字數 1848 閱讀 3841

我最近在leetcode上擼了乙個小演算法,雖然已經工作了五年,當看到每次**提交後排名的提公升,內心依然很有成就感。題目比較簡單,求小於n的素數個數,素數也叫質數,具有以下特點:

根據上面的特點,我們還可以推斷出:

依據這一點,我們可以寫出下面的實現:

class

solution

intcount = 1;// 2

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

}if (isprime)

}return

count;}}

j * j <= i相當於j <= math.sqrt(i),但速度會快一點,那為什麼只需要判斷到√i呢,因為對於乙個非素數(合數),其最小約數(除1外)必小於等於其平方根。

這個實現被accept了,但時間複雜度較高,排名也很靠後。這個演算法中,判斷乙個奇數i是不是素數,是通過試除小於等於√i的奇數來實現,這會有重複計算的場景,比如3和9,5和15,根據素數和合數的特點,可以推斷出任意乙個合數都可以分解成幾個素數的乘機,所以我們可以通過試除小於等於√i的素數來判斷i是不是素數,素數相對於奇數,無疑減少了很多判斷次數。

class

solution

intcount = 0;

int primes = new

int[n / 2];

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

}if (isprime)

}return

count + 1;// 2}}

效果好了一些,但這個實現時間複雜度依然很高,比試除法更高效的是篩選法,篩選法的策略是將素數的倍數全部篩掉,剩下的就是素數了,下圖很生動的體現了篩選的過程:

篩選的過程是先篩掉非素數,針對本文的題目,每篩掉乙個,素數數量-1即可,上面說過素數的乙個特點,除了2,其它的素數都是奇數,所以我們只需在奇數範圍內篩選就可以了。

class

solution

intcount = n / 2;// 篩掉一半偶數

boolean notprime = new

boolean[n];

for (int i = 3; i * i < n; i += 2) }}

}return

count;}}

示例35

791113

1517

1921

2325

2729

備註i=3

3579

1113

1517

1921

2325

2729

3->9,15,21,27

i=53

57911

1315

1719

2123

2527

295->25

對於乙個奇數i,會依次篩掉i*i,i(i+2),i(i+4),i(i+6)…i(i+2n),那麼為什麼不篩3i,5i,7i…(i-4)i,(i-2)i呢,因為他們已經被篩過了,當我們要篩掉奇數i的倍數時,那麼i之前的奇數(i-2,i-4…7,5,3)的倍數((i-2)i,(i-4)i…7i,5i,3i)已經被篩掉了,這個演算法的效果還不錯。

MPI求素數個數

附上另乙個呼叫函式後針對乙個輸入正確 include stdafx.h include mpi.h include stdio.h include string.h include math.h int isprime int n return flag int main int argc,char...

48 求質數 素數 個數

48 求質數 素數 個數 問題描述 求出所有的大於等於n小於等於m的質數,統計其數目。n m 輸入說明 你的程式需要從標準輸入裝置 通常為鍵盤 中讀入多組測試資料。每組一行,每行包含兩個整數n m n m都不大於20000 兩組資料之間沒有多餘的空行。在行首和行尾沒有多餘的空格。輸出說明 對每組測試...

篩素數,求區間內素數個數

問題 1525 藍橋杯 演算法提高vip 找素數 時間限制 1sec 記憶體限制 128mb 提交 1179 解決 133 題目描述 給定區間 l,r 請計算區間中素數的個數。資料規模和約定 2 l r 2147483647 r l 1000000 輸入兩個數l和r。輸出一行,區間中素數的個數。樣例...