📅  最后修改于: 2023-12-03 15:13:44.871000             🧑  作者: Mango
素数是只能被1和自身整除的正整数,本文将介绍如何使用C/C++编程查找给定范围之间的素数。
最简单的方法是对于每一个数,从2到其自身减一,判断有没有能够整除它的数。但是这种方法时间效率很低,无法处理大数。常见的优化算法有:
试除法是最基本的素数判断方法,它的原理是如果一个数能被整除,那么它只能被小于等于它的数整除。
实现思路是:枚举每个数i,从2到i/2,看i是否有整除数。
埃拉托斯特尼筛法的原理是将小于等于一个数的所有素数找出来,然后再筛去这些素数的倍数,剩下的数即为素数。
实现思路是:将小于等于n的所有数先标记为合数,然后从2开始枚举每个素数,将其倍数标记为不是素数。最终,剩下的标记为合数的数就是素数。
Miller-Rabin算法是一种基于概率的算法,它可以快速地判断一个数是否为素数。
实现思路是:对于一个大数n,它是一个合数可能性很高,我们可以选择一些随机的底数a,判断它是否是n的一次方或平方的余数。经过多次测试后,如果每次测试结果都表明n是素数,那么n就极有可能是素数。
在本文代码实现中,我们主要采用了试除法和埃拉托斯特尼筛法两种算法。
#include <cstdio>
#include <cstdlib>
// 判断是否为素数,1表示是,0表示否
int is_prime(int n)
{
if (n == 1) {
return 0; // 1不是素数
}
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return 0; // 可以被整除,不是素数
}
}
return 1;
}
int main()
{
int lower, upper;
printf("请输入范围:\n");
printf("下界:");
scanf("%d", &lower);
printf("上界:");
scanf("%d", &upper);
for (int i = lower; i <= upper; i++) {
if (is_prime(i)) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
// 判断是否为素数,1表示是,0表示否
int is_prime(int n, int *prime, int len)
{
for (int i = 0; i < len && prime[i] <= sqrt(n); i++) {
if (n % prime[i] == 0) {
return 0; // 可以被整除,不是素数
}
}
return 1;
}
// 埃拉托斯特尼筛法,返回素数的个数
int eratosthenes(int upper, int *prime)
{
int cnt = 0;
char *flag = new char[upper + 1];
memset(flag, 0, sizeof(char) * (upper + 1));
for (int i = 2; i <= upper; i++) {
if (!flag[i]) {
prime[cnt++] = i;
for (int j = i + i; j <= upper; j += i) {
flag[j] = 1;
}
}
}
delete[] flag;
return cnt;
}
int main()
{
int lower, upper;
printf("请输入范围:\n");
printf("下界:");
scanf("%d", &lower);
printf("上界:");
scanf("%d", &upper);
int *prime = new int[upper + 1]; // 保存素数
int cnt = eratosthenes(upper, prime);
for (int i = lower; i <= upper; i++) {
if (is_prime(i, prime, cnt)) {
printf("%d ", i);
}
}
printf("\n");
delete[] prime;
return 0;
}
本文介绍了基本的素数判断算法和优化算法,并给出了C/C++代码实现。优化算法在处理大数时效率更高,特别是埃拉托斯特尼筛法,时间复杂度为O(nloglogn),空间复杂度为O(n)。科学计算中常常需要大量素数,因此掌握算法对于科研类开发人员具有重要意义。