如下
这道题是leetCode中初级算法中的一题,算法面试中还是比较常见的,要求统计数字n以内的素数个数涉及到这种统计类的题,大多没有接触过算法的人可能第一想到的就是暴力统计
一.暴力统计
整理一下思路: 判断一个数是不是素数,就是判断除了1 和它本身之外还能不能被其他数整除,也就是说,当前数为 i,i 如果能被 2~(i-1) 之间的任何一个数整除,就代表这个数不是素数,仔细理解下,开始编码
public class ArithmeticTest {
/**
* 统计数字n以内的素数个数
* 素数:只能被1 和本身整除的自然数 0和1 除外
* 例 输入 100 输出 25
*/
public static void main(String[] args) {
long start = System.currentTimeMillis();
// 为了性能对比 统计100000以内的
int count = violenceStatistical(100000);
System.out.println("共有素数个数:" + count);
long end = System.currentTimeMillis();
System.out.println("耗费时间:" + (end - start));
}
//暴力算法
private static int violenceStatistical(int n) {
//计数器
int count =0;
//遍历n 从2开始 0和1 直接排除
for(int i=2;i<n;i++){
//判断 i是素数 count+1,非素数 count+0
count+=isPrime(i)?1:0;
}
return count;
}
private static boolean isPrime(int i) {
//x 取值范围 2~(i-1)
for(int x=2;x<i;x++){
//判断 如果 x能被i整除,代表不是素数
if(i%x==0){
return false;
}
}
return true;
}
}
打印结果如下,花费了 6768ms
二.埃筛法
整理思路:首先将2到n范围内的整数写下来,其中2是最小的素数。将表中所有的2的倍数划去,表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数。再将表中所有的3的倍数划去……以此类推,如果表中剩余的最小的数是m,那么m就是素数。然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内的素数,仔细理解下,编码如下
public class ArithmeticTest {
/**
* 统计数字n以内的素数个数
* 素数:只能被1 和本身整除的自然数 0和1 除外
* 例 输入 100 输出 25
*/
public static void main(String[] args) {
long start = System.currentTimeMillis();
// 为了性能对比 统计100000以内的
int count = eratosthenesStatistical(100000);
System.out.println("共有素数个数:" + count);
long end = System.currentTimeMillis();
System.out.println("耗费时间:" + (end - start));
}
//埃筛法
private static int eratosthenesStatistical(int n) {
//声明一个长度为n的数组,布尔默认值是false,全是素数
boolean[] isPrime=new boolean[n];
//计数器
int count =0;
//遍历 从2开始 0和1 直接排除
for(int i=2;i<n;i++){
//如果为true就跳过
if(!isPrime[i]){
count++;
//系数倍增,比如2 ,将数组中2的倍数都设置为true
for(int j=2 *i;j<n;j+=i){
isPrime[j]=true;
}
}
}
return count;
}
//暴力算法
private static int violenceStatistical(int n) {
//计数器
int count =0;
//遍历n 从2开始 0和1 直接排除
for(int i=2;i<n;i++){
//判断 i是素数 count+1,非素数 count+0
count+=isPrime(i)?1:0;
}
return count;
}
private static boolean isPrime(int i) {
//x 取值范围 2~(i-1)
for(int x=2;x<i;x++){
//判断 如果 x能被i整除,代表不是素数
if(i%x==0){
return false;
}
}
return true;
}
}
看下打印结果 17ms!