素数是整数王国的基石,理解素数的性质对解决整数问题十分必要。
同时,对素数的判定也是初学者练习算法技巧的难得素材。
1.试除法
判断一个数N是否是素数,从2---N-1之间判断看是否有可以整除N
1既不是素数也不是合数
1.1 2---N-1
package NO5;
public class Test5 {
//试除法
/*
static void f(int n){
boolean isPrime = false;
for(int i = 2; i <= n-1;i++){
if(n % i == 0)
isPrime = true;
}
}*/
static void f(int n){
for(int i = 1; i <= n; i++){
boolean isPrime = true;
if(i == 2){
System.out.println(i);
}
else {
for(int j = 2;j <= i-1;j++){
if( i % j == 0){
isPrime = false;
//System.out.println(i);
break;
}
}
if(isPrime)
System.out.println(i);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
f(100);
}
}
当n很小时候,所用时间还可以
当n = 10000000,我感觉10分钟都跑不出来结果来= =
1.2 2---N/2 2-sqrt(N) 这样可以一下子去掉一半的步骤,提高了效率
package NO5;
public class Test5 {
static void f(int n){
for(int i = 1; i <= n; i++){
boolean isPrime = true;
if(i == 2){
System.out.println(i);
}
else {
for(int j = 2;j <= i/2;j++){ // j < =Math.sqrt(i);
if( i % j == 0){
isPrime = false;
//System.out.println(i);
break;
}
}
if(isPrime)
System.out.println(i);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
f(10000000);
}
}
2.素数筛选法
package NO5;
public class Test6 {
static void f(int N){
byte[] b = new byte[N];//默认初始都是0,如果为1则表示为不是素数,如果为0则表示为素数
for(int i = 2 ; i < N/2;i++){
//为何是N/2呢? 反思 if(b[i] == 1) continue;
for(int k = 2;k * i < N;k++){
b[k*i] = 1;
}
}
int num = 0;
for(int i = N-1; num < 10;i--){
if(b[i] == 0){
System.out.println(i);
num++;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int N = 1000* 1000* 10;
f(N);
}
}
结果:
9999991
9999973
9999971
9999943
9999937
9999931
9999929
9999907
9999901
9999889
筛选法: 如一个数能够被4整除,则该数必然能被2整除
首先byte数组的初始值为0,默认初始均为素数
从2开始一直到N/2, 先排除2的倍数,接着排除3的倍数,以此类推
代码非常简明,
使用数组存放已经找到的素数。
以此为基础寻找下一个素数,即从最大素数向上寻找,用已经有的素数试除。
用这个方法求第100001个素数,看看耗时情况。
package NO5;
//第05讲-素数与筛法_数组存素数
public class Test7 {
static void f(int N){
int[] Prime = new int[N/2];
int index = 0;
for(int i = 2; i < N/2; i++){
boolean isPrime = true;
for(int j = 0; j < Prime.length && Prime[j] != 0; j++){
if(i % Prime[j] == 0){
isPrime = false;
break;
}
}
if(isPrime){
Prime[index++] = i;
//System.out.println(Prime[index-1]);
}
}
int count = 0;
//System.out.println(Prime[100001]);
for(int i = 0; i < Prime.length; i++){
if(Prime[i] != 0)
count++;
}
System.out.print(count);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int N = 1000 * 1000 * 10;
//int N = 1000 * 1000 * 10;
long startTime = System.currentTimeMillis();
f(N);
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}
这么课程,我延误了快二周了,完了,完成了33%,我得哭去,提交的71%
= =好多都是延误提交= =
好烦= =