1. 程式人生 > >求解1到n之間素數的個數

求解1到n之間素數的個數

常用方法:

package test;

import java.util.Scanner;

public class PrimeCount {
	//判斷一個數是否為素數的時間複雜度為O(sqrt(n))
	boolean isPrime(int num){
		if(num < 2)
			return false;
		int i = 2;
		for(;i*i<=num;i++){
			if(num %i==0)
				break;
		}
		if(i*i >num)
			return true;
		return false;
	}
	public static void main(String[] args) {
		PrimeCount pc = new PrimeCount();
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int count = 0;
		for(int i =1;i<=n;i++){
			if(pc.isPrime(i))
				count++;
		}
		sc.close();
		System.out.println(count);
	}
}

上述演算法的時間複雜度為O(n*sqrt(n));

2、埃拉託斯特尼篩法:

給出要篩數值的範圍n,找出\sqrt{n}以內的素數p_{1},p_{2},\dots,p_{k}。先用2去篩,即把2留下,把2的倍數剔除掉;再用下一個質數,也就是3篩,把3留下,把3的倍數剔除掉;接下去用下一個質數5篩,把5留下,把5的倍數剔除掉;不斷重複下去......。

程式碼實現:
package test;

import java.util.Scanner;

public class PrimeCount {

	int primeFilter(int num){
		boolean array[] = new boolean[num+1];
		for(int i = 2;i<=num;i++){
			array[i] = true;
		}
		int count =0;//素數個數
		for(int i=2;i*i<=num;i++){
			if(!array[i])//不是素數
				continue;
			//將當期素數的倍數置為false,為合數
			int j= i*2;
			while(j<=num){
				if(array[j])
					array[j]= false;
				j+=i;
			}
		}
		for(boolean bool:array)
		{
			if(bool)
				count++;
		}
		return count;
	}
	public static void main(String[] args) {
		PrimeCount pc = new PrimeCount();
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int count = 0;
		long start = System.currentTimeMillis();
		count = pc.primeFilter(n);
		long end = System.currentTimeMillis();
		System.out.println("time use:"+(end-start));
		sc.close();
		System.out.println(count);
	}
}
時間複雜度為O(n*loglog(n)),接近於線性時間