素数:只有1和本身两个约数的数
一、判断素数
算法核心思想:遍历i从2到 n \sqrt{n} n,判断i是否为n的因子
程序代码:
import java.util.Scanner;
public class PrimeCheck {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int n = sc.nextInt();
System.out.println(isPrime(n)?"yes":"no");
}
}
public static boolean isPrime(int n) {
if(n<=1) return true;
for(int i=2;i*i<=n;i++) if(n%i==0) return false;
return true;
}
}
二、埃氏筛法
算法核心思想:将素数的倍数标记为合数
缺点:会出现多次筛选的情况,比如合数12,在素数2的倍数中已经被筛选过一次,又在素数3的倍数中又筛选过一次,导致算法的效率较低。
程序代码:
import java.util.Arrays;
public class SieveOfEratosthenes {
public static void main(String[] args) {
int n = 100;
boolean isprime[] = new boolean[n+1];
Arrays.fill(isprime, true);
isprime[0] = false;
isprime[1] = false;
for(int i=2;i*i<=n;i++) {
if(isprime[i]==true) {
for(int j=2;i*j<=n;j++) {
isprime[i*j] = false;
}
}
}
int count = 0;
for(int i=2;i<n;i++) {
if(isprime[i]==true) {
count++;
System.out.println(i);
}
}
System.out.printf("从1到%d共有%d个素数",n,count);
}
}
三、欧拉筛法
算法核心思想:每个合数只被其最小的素因子筛一次
程序代码:
public class SieveOfEuler{
public static void main(String[] args) {
final int MAX = 100;
int[] prime = new int[MAX];//找到的具体素数
boolean[] isp = new boolean[MAX+5];//标记下标对应的整数是否是某个素数的倍数(倍数>=2)
int count = 0;//有多少个素数
for(int i=2;i<MAX;i++) {
if(isp[i]==false) {
prime[count++] = i;//把当前素数i存放到prime数组第count个位置,然后count+1
}
for(int j=0;j<count && i*prime[j]<=MAX;j++) {
isp[i*prime[j]] = true;//prime[j]素数的i倍一定是合数
if(i%prime[j]==0) break;
//i=prime[j]*k,i*prime[j+1]=prime[j]*(k*prime[j+1])
//i*prime[j+1]它应该被k*prime[j+1]这个数去筛掉,因为它有更小的素因子prime[j]
}
}
for(int i=0;i<count;i++) {
System.out.println(prime[i]);
}
System.out.printf("从1到%d共有%d个素数", MAX, count);
}
}