1. 有时候不是判断某个素数而是需要求解第k个素数,这个时候如果使用传统的方法来判断是否是素数来计数的话耗时比较多,在这个情况下我们解决这个问题之前需要了解素数定理
素数定理描述素数的大致分布情况, 一个个地看,素数在正整数中的出现没有什么规律。可总体地看,素数的个数有规可循。对正实数x,定义π(x)为不大于x的素数个数。数学家找到了一些函数来估计π(x)的增长。以下是第一个这样的估计:π(x)≈x/ln x ,其中ln x为x的自然对数。上式的意思是当x趋近∞,π(x) 和x/ln x的比趋近1(注:该结果为高斯所发现)。但这不表示它们的数值随着x增大而接近。
意思就是0- x之间大概有x / Inx个素数
假如求解第k个素数那么需要开辟的空间为多少呢?通过上面的素数定理我们可以知道: 在循环中我们可以判断 x / In x < n,等式成立的话对x进行加1,这样我们就解决了开辟多少长度区间的问题,然后下面进行2-x之间的数字进行筛选,把2,4,6,8....倍数的3,6,9,..4,8,12...倍数的.....的不是素数的标记一下,剩下来的没有标记的就是素数 然后进行计数当计数达到k的时候返回
2. 下面是具体的代码
import java.util.Scanner;
import static java.lang.StrictMath.log;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
solve(n);
}
public static void solve(long n) {
long now = System.currentTimeMillis();
int x = 2;
while(x / log(x) < n){
x++;
}
//System.out.println(x);
int arr[] = new int[x];
for(int i = 2;i < x; i++){
if(arr[i]!=0){
continue;
}
int k = 2;
while(i * k < x){
arr[i * k] = -1;
k++;
}
}
int sum = 0;
for(int i = 2; i < x; i++){
if(arr[i]==0)sum++;
if(sum==n){
System.out.println(i);
long end = System.currentTimeMillis();
System.out.println("耗时"+(end-now)+"ms");
return;
}
}
}
}