求素数个数(两种方法+针对本题做出的改进)(Java)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/l870358133/article/details/102091410

求素数的个数。本题要求编写一个程序,求1~n的素数个数。 要求至少给出两种解法,对于相同的n,给出这两种解法的结果,通过相关数据进行测试,目的是通过对比同一问题不同解法的绝对执行时间体会如何设计“好”的算法。

时间限制: 200 ms

内存限制: 64 MB

代码长度限制: 16 KB

输入格式:

输入在一行中给出1个整数n(<= 10 000 000)。

输出格式:

对每一组输入,在一行中输出1~n的素数个数。

输入样例1:

5

输出样例1:

3

输入样例2:

14

输出样例2:

6

 第一种方法:

import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int sum = 1;
		if(n==1) 
			System.out.println("0");
		else if(n==2)
			System.out.println("1");
		else {
			for(int i=3;i<=n;i++) {
				int j=2;
				int size=(int)Math.sqrt(i);
				for(;j<size;j++) {
					if(i%j==0)
						break;
				}
				if(j==size) {
					sum++;
				}
			}
			System.out.println(sum);
		}
	}
}

第二种方法(埃氏筛法):

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] num = new int[n+1];
		int sum = 0;
		for(int i=2;i<=n;i++) {
			if(num[i]==0) {
				sum++;
				int j=i+i;
				while(j<=n) {
					num[j]=1;
					j+=i;
				}
			}
		}
		System.out.println(sum);
	}
}

最终改进后:

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] num = new int[n+1];
		int sum = 1;
		if(n<=1)
			System.out.println(0);
		else if(n==2)
			System.out.println(1);
		else {
			for(int i=3;i<=n;i+=2) {
				if(num[i]==0) {
					sum++;
					int tmp = i+i;		//存值 i+i,减少运算次数,相当于跳过了偶数次的运算,因为偶数除了2不会再有素数
					int j=tmp+i;		//相当于3个i相加
					while(j<=n) {
						num[j]=1;
						j+=tmp;
					}
				}
			}
			System.out.println(sum);
		}
	}
}

这个题让我真的从时间上感受到了代码的“好坏”,这应该还不是最简的方法,因为我依然没有拿到全分,还是有一个测试点运行超时了,200ms的运行时间确实很考验人。第一种方法就是最基本的方法,一般初学者刚开始学用的最多的方法;第二种我建立了一个数组,因为1不算,从2开始进行判断,素数自身的倍数是合数,我的思路是把n个数遍历一遍,在遍历前面的数时直接把明确是合数的标记出来,则在遍历的过程中未标记的就是素数,虽然没能拿到全分,但这种方式相较于第一种在时间上还是有一个提升;第三种方法是第二种方法的改进,因为除2以外的偶数都是合数,所以直接不再去考虑偶数,相当于减少了一半的计算量,但结果还是超时了,实在没办法了。至于最终能拿全分的正解,等我克服掉以后再回来补充。。。如果有了解这个题正解的,麻烦告诉我怎么做,我实在是懵了。

猜你喜欢

转载自blog.csdn.net/l870358133/article/details/102091410