給定整數n,請問n以內有多少個素數?
摘自挑戰程式程式設計。
要列舉n以內素數,可以用埃氏篩法。這是乙個與輾轉相除法一樣古老的演算法。
首先,將2到n範圍內的所有整數寫下來。其中最小的數字2是素數。將表中所有2的倍數都劃去。表中剩餘的最小數字是3,它不能被更小的數整除,所以是素數。在將表中所有3的倍數都劃去。以此類推,如果表中剩餘的最小數字是m時,m就是素數。然後將表中所有m的倍數都劃去。像這樣反覆操作,就能列舉n以內的素數。
int prime[max_n];
bool is_prime[max_n+1];
int sieve(int n)
}return p;
}
尤拉篩法則可以把埃氏篩法優化到0(n)
每個合數只用其最小的乙個質因數去篩,這便是尤拉篩了
有一句關鍵並且神奇的**。
if (i
% primes[j] == 0) break;
根據大佬的部落格解釋:
prime陣列中的素數是遞增的,當i能整除prime[j],那麼i*prime[j+1]這個合數肯定被prime[j]乘以某個數篩掉。
因為i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那麼i*prime[j+1]=(k*prime[j])*prime
[j+1]=k』*prime[j],接下去的素數同理。所以不用篩下去了。因此,在滿足i%prime[j]==0這個條件之前以及第一次
滿足改條件時,prime[j]必定是prime[j]*i的最小因子。
void euler_sieve(int n)
}}
素數之埃氏篩法 尤拉篩法
判斷數n是否為乙個素數,基本方法為從2開始向後列舉,若n不能被2,3,4,n 1整除,則n為素數,該判斷方法的時間複雜度為o n o n o n 更快的方法為,當列舉至n sqrt n n 時即可判斷是否為素數,該判斷方法的時間複雜度為o n o sqrt n o n 如下 寫法1,其中sqrt函式...
素數篩法 埃氏篩及尤拉篩
在做題中會經常遇到有關素數的問題,整理一下學過的兩種素數篩法。時間複雜度 o nloglogn 我們知道乙個素數的倍數肯定是乙個合數,乙個合數可以由多個素數相乘得到,所以可以從2開始把2的倍數篩一遍,找到下個素數在篩一遍。篩完後素數的倍數都被篩掉了,剩下的就是素數。如下 const int n 1e...
線性篩法求素數(埃氏篩法 尤拉篩法)
篩法都是初始化把所有數都先設為素數,然後篩除合數。理解起來比較簡單,就是從小到大的列舉每乙個數,標記它的所有倍數都是合數 非素數 放到u i 為false,u中的下標對應的就是這個數的值。bool u maxn int num,su maxn 1.埃氏篩法 void prime 從小到大的篩選素數,...