您的位置:首页 > 房产 > 家装 > 河北通信网站建设_免费自助建站全系统_软文300字介绍商品_友妙招链接

河北通信网站建设_免费自助建站全系统_软文300字介绍商品_友妙招链接

2025/5/9 10:27:45 来源:https://blog.csdn.net/2301_80093604/article/details/146325837  浏览:    关键词:河北通信网站建设_免费自助建站全系统_软文300字介绍商品_友妙招链接
河北通信网站建设_免费自助建站全系统_软文300字介绍商品_友妙招链接

判断一个数是否是质数(素数)是一个经典的算法问题。质数是指大于 1 的自然数,且只能被 1 和它本身整除的数。以下是几种常见的判断质数的算法及其优化。


1. 朴素算法

从 2 到 n-1 逐一检查是否能整除 n。如果能被整除,则 n 不是质数。

bool isPrime(int n) {if (n <= 1) return false; // 1 及以下的数不是质数for (int i = 2; i < n; i++) {if (n % i == 0) return false; // 如果能被整除,不是质数}return true; // 否则是质数
}

时间复杂度O(n)
缺点:效率低,尤其对于大数。


2. 优化:只检查到 √n

如果一个数 n 不是质数,那么它一定有一个因数小于或等于 √n。因此,只需要检查到 √n 即可。

bool isPrime(int n) {if (n <= 1) return false;for (int i = 2; i * i <= n; i++) { // 只需检查到 √nif (n % i == 0) return false;}return true;
}

时间复杂度O(√n)
优点:效率显著提高。


3. 进一步优化:跳过偶数

除了 2,所有偶数都不是质数。因此,可以跳过所有偶数。

bool isPrime(int n) {if (n <= 1) return false;if (n == 2) return true; // 2 是质数if (n % 2 == 0) return false; // 排除偶数for (int i = 3; i * i <= n; i += 2) { // 只检查奇数if (n % i == 0) return false;}return true;
}

时间复杂度O(√n),但实际运行时间减半。


4. 进一步优化:6k ± 1 规则

所有质数(除了 2 和 3)都可以表示为 6k ± 1 的形式。因此,可以只检查形如 6k ± 1 的数。

bool isPrime(int n) {if (n <= 1) return false;if (n <= 3) return true; // 2 和 3 是质数if (n % 2 == 0 || n % 3 == 0) return false; // 排除 2 和 3 的倍数for (int i = 5; i * i <= n; i += 6) { // 只检查 6k ± 1 的数if (n % i == 0 || n % (i + 2) == 0) return false;}return true;
}

时间复杂度O(√n),但实际运行时间更少。


5. 素数筛法(适合批量判断)

如果需要判断多个数是否是质数,可以使用 埃拉托斯特尼筛法(Sieve of Eratosthenes)预处理。

#include <vector>
#include <cmath>vector<bool> sieve(int n) {vector<bool> isPrime(n + 1, true);isPrime[0] = isPrime[1] = false;for (int i = 2; i * i <= n; i++) {if (isPrime[i]) {for (int j = i * i; j <= n; j += i) {isPrime[j] = false;}}}return isPrime;
}bool isPrime(int n) {if (n <= 1) return false;vector<bool> primes = sieve(n);return primes[n];
}

时间复杂度O(n log log n)(预处理),O(1)(查询)。
优点:适合批量判断。


6. Miller-Rabin 素性测试(适合大数)

对于非常大的数(如 100 位以上的数),可以使用 Miller-Rabin 素性测试。这是一种概率算法,但可以通过多次测试将错误率降到极低。

#include <cstdlib>
#include <ctime>using ll = long long;ll power(ll a, ll d, ll n) {ll result = 1;a = a % n;while (d > 0) {if (d % 2 == 1) result = (result * a) % n;d = d >> 1;a = (a * a) % n;}return result;
}bool millerTest(ll d, ll n) {ll a = 2 + rand() % (n - 4);ll x = power(a, d, n);if (x == 1 || x == n - 1) return true;while (d != n - 1) {x = (x * x) % n;d *= 2;if (x == 1) return false;if (x == n - 1) return true;}return false;
}bool isPrime(ll n, int k = 5) {if (n <= 1 || n == 4) return false;if (n <= 3) return true;ll d = n - 1;while (d % 2 == 0) d /= 2;for (int i = 0; i < k; i++) {if (!millerTest(d, n)) return false;}return true;
}

时间复杂度O(k log³ n),其中 k 是测试次数。
优点:适合大数判断。


总结

  • 对于小范围数(如 n ≤ 10^6),使用 优化到 √n6k ± 1 规则 的算法即可。
  • 对于大范围数(如 n ≤ 10^12),可以使用 Miller-Rabin 素性测试
  • 如果需要批量判断,使用 埃拉托斯特尼筛法

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com