质数算法 判断质数 小于n的质数 前n个质数

场景一:输入一个整数n,判断n是否为质数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 判断是否是质数
* 思路(依次优化)
* 1. 从2到n-1遍历判断
* 2. 从2到n/2遍历判断
* 3. 从2到√n遍历判断
* 4. 从2到√n中所有奇数进行遍历
* 5. 从2到√n中所有质数进行遍历
* @param n 参数1
* @return 是否是质数
*/
public static boolean isPrime(int n){

if(n<=1)
return false;
if(n==2||n==3)
return true;
if(n%2==0)
return false;

for(int i=3;i*i<=n;i+=2){
if(n%i==0)
return false;
}

return true;
}

参考链接:计蒜客【挑战难题】系列讲解(三)判断质数

场景二:输入一个整数n,输出小于n的所有质数,并返回质数个数。

思路:判断是否>=2,如果是则遍历2到n区间的所有数并做“是否为质数”的判断;显然这样做需要计算量太大了。常用的较快算法采用空间来换取时间,借组一个n+1空间的数组,该数组的下标对应[0-n]区间整数,其中下标为0和下标1不需要用到。然后把质数2、3、7…N(小于n)的倍数(>=2)全部标记,最后数组剩下没有被标记的为所求质数集。如下图,绿色代表当前质数,红色代表已经被标记,从下标数组下标2到n+1依次扫描,当扫到的时质数的(刚好值为FALSE),就开始标记。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//方法一  时间复杂度接近O(nlogn)
public static int printNA(int n){

int result =0;

for(int i=0;i<n;i++){
if(isPrimeC(i)){
System.out.println(i);
result++;
}
}
return result;
}

public static boolean isPrimeC(int n){

if(n<=1)
return false;
if(n==2||n==3)
return true;
if(n%2==0)
return false;

for(int i=3;i*i<=n;i+=2){
if(n%i==0)
return false;
}

return true;
}


//方法二 以空间换时间
public static int printNB(int n){

if(n<=1)
return 0;

boolean[] flags = new boolean[n+1];

for(int i=0;i<flags.length;i++)
flags[i]=true;

for(int i=2;i<flags.length;i++){
if(flags[i]){
int count = n/i;
for(int j=2;j<=count;j++){
flags[i*j]=false;
}
}
}

int result =0;

for(int i=2;i<flags.length;i++){
if(flags[i]){
System.out.println(i);
result++;
}
}
return result;
}

场景三:输入一个整数n,输出前n个质数。

思路:当n比较小的时候可以采用遍历法;当n比较大的时候,由于质数的分布式越来越稀疏,意味着n个质数可能分布在[2,N]区间中,N会很大。由n和N/InN在数学上的关系相对紧密,所以可由n算出N,然后再利用“场景二”求出N区间内的质数后再输出前n个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// n比较小的时候
public static void printNA(int n){

if(n<=0)
return;
int count=0;
for(int i=2;;i++){
if(isPrime(i)){
System.out.println(i);
count++;
if(count==n)
break;
}
}

}

public static boolean isPrime(int n){

if(n<=1)
return false;
if(n==2||n==3)
return true;
if(n%2==0)
return false;
for(int i=3;i*i<=n;i+=2){
if(n%i==0)
return false;
}
return true;
}


// n 比较大的时候
public static void printNB(int n) {

if (n < 1)
return;

int m = (int) Math.pow(Math.pow(n, Math.E),1.0/(Math.E-1));

if (n == 1) {
System.out.print(2);
return;
}

boolean[] flags = new boolean[m + 1];

for (int i = 0; i < flags.length; i++)
flags[i] = true;

for (int i = 2; i < flags.length; i++) {
if (flags[i]) {
int count = m / i;
for (int j = 2; j <= count; j++) {
flags[i * j] = false;
}
}

}

int count = 0;

for (int i = 2; i < flags.length; i++) {
if (flags[i]) {
System.out.println(i);
count++;
}
if (count >= n)
break;
}

}

参考链接:【质数算法】——判断质数、求小于N的质数、求前N个质数

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器