质数是指在大于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