質數是指在大於1的天然數中,除了1和它自己之外再也不有其餘因數的天然數。算法
int isprime(int x) { if (x < 2) return false; // 小於2的數都不是質數 for (int i = 2; i < x; i++) if (x % i == 0) return false; return true; }
顯然這個算法的複雜度爲\(O(n)\)。數組
咱們知道,一個數若是能夠進行因數分解,那麼分解時獲得的兩個數必定是一個小於等於\(sqrt(n)\),一個大於等於\(sqrt(n)\)。因此,循環沒有必要從\(2\)到\(x-1\),只須要從\(2\)到\(sqrt(n)\)就行了,那麼這個算法的時間複雜度就爲\(O\left(sqrt(n)\right)\)。優化
int isprime(int x) { if (x < 2) return false; // 小於2的數都不是質數 for (int i = 2; i <= int(sqrt(x)); i++) // 從2到sqrt(x) if (x % i == 0) return false; return true; }
固然,這個算法還能夠繼續優化,咱們能夠判斷2是否是這個數的約數,而後就能夠從\(3\)開始循環到\(sqrt(n)\)了,每次循環\(i+2\),那麼這個算法的複雜度就爲\(O(sqrt(n)/2)\)。spa
int isprime(int x) { if (x < 2) return false; // 小於2的數都不是質數 if (x != 2 && x % 2 == 0) return false; // 不是2且能被2整除的數都不是質數 for (int i = 3; i <= int(sqrt(x)); i += 2) // 每次循環加2 if (x % i == 0) return false; return true; }
即便是上述的算法,在遇到很大的數字\((n\ge{100,000,000})\)的時候,仍是很慢。
那還有沒有更快的算法呢?答案是有的,埃拉託斯特尼篩法就是其中之一。.net
咱們能夠把從\(2\)到\(maxn\)的數儲存爲一張表,例如bool prime[MAXN];
。
而後咱們一詞遍歷這個數組,把\(i\)的倍數從數組中去掉,這樣咱們就獲得了一張從\(2\)到\(maxn\)的質數的表。
須要判斷一個數是否爲質數的時候只須要查詢這張表就能夠了,例如if (prime[i]) // 你的操做
。code
void getPrime(int maxn) { for (int i = 0; i <= maxn; i++) prime[i] = 1; // 所有定義爲質數 prime[0] = prime[1] = 0; for (int i = 2; i <= maxn; i++) { if (!prime[i]) continue; for (int j = i * 2; j <= maxn; j += i) prime[j] = 0; // i的倍數標記爲合數 } }
素數的四種判斷方法、實現及比較:http://www.javashuo.com/article/p-nnilbdev-eh.htmlblog