定义:对于给定正数n,若对于任意在正整数a(0<a<n),都有n%a成立,那么成为素数(质数),否则成为和树
下面解决两个问题:
1.如何判断一个数为素数
2.如和尽快的生成1~n的素数表
- 如何判断一个数为素数
按照定义即可判断一个数是否为素数
方法一:对于给定正数n,若对于任意在正整数a(0<a<n),都有n%a成立,那么成为素数(质数)
代码实现:
#include <iostream>
using namespace std;
bool isprime(int n){
if(n <= 1)
return false;
for(int i = 2; i < n;i++){
if(n% i == 0)
return false;
}
return true;
}
需要注意1既不是素数也不是合数。
此算法时间复杂度为O(n),有没有什么方法可以让时间复杂度下将呢?
方法二:
由n%k == 0且n*(n/k) =n,这启发我们n/k 和k之间必定有一个大于等于sqrt(n/k)
所以我们只用判断2~sqrt(n/k)之间的数即可。
代码实现:
bool isprime(int n){
if(n <= 1)
return false;
int sqr = (int)sqrt(1.0*n); //sqrt里面参数类型为浮点数,乘上1.0将其转化为浮点数
for(int i = 2; i <= sqr;i++){
if(n% i == 0)
return false;
}
return true;
}
- 如和快速的获取1~n之间的素数
方法一:
对1~n之间的每个数都判断一下是否为素数,若为素数,则加进素数表。
(对时间复杂度为10^5都没有什么问题)
代码实现:
const int maxn = 101;
int prime[maxn];
bool p[maxn] ={0};
int num = 0;
void find_prime(){
for(int i = 1; i < maxn;i++){
if(isprime(i)){
prime[num++] = i; //将素数存入表中
p[i] = true;
}
}
}
方法二:埃氏晒法
算法思想:
从小到大枚举所有数,对于每一个素数,晒去他的所有倍数2,剩下的就为素数了。
代码实现:
const int maxn = 101;
int prime[maxn], num = 0;
bool p[maxn] = {0};
void find_prime()
{
for(int i = 2; i < maxn; i++){
if(p[i] == false){
prime[num++] = i;
for(int j =i+ i; j < maxn; j+=i )
p[j] = true; //筛除i的倍数
}
}
}