两个程序写了3个多小时,时间基本都花在查资料,Debug上。Java用法不熟悉,一些数学函数(Java中称数学方法更合适?)的使用,比如开根号,求ln,都是直接在网上查的;
改进定义的方法已经写了3遍了,感觉还是不是很溜。特别是对于isPrime放在哪里迷迷糊糊,嵌套for循环感觉让思路很混乱。自己写了一遍流程图才稍微明朗点,果然是智商不够用么。。。
筛选法第一次写。这次先写了流程图,果然在写程序的时候思路清晰很多。不过,写完第一遍各种数组越界,除数中有零,本质都是数组下标的运算不严紧。。。幸好Java能提示越界,要是C的话,估计又要自己Debug半天(还未必能看出来)。。。。对于这些细节在写的时候确实没有考虑进去,需要下标运算的时候,就把数组范围和对应的下标注释出来。
基本都是在处理越界问题,最后实在Debug不出来了,只能重新梳理流程和各部分功能,逐个验证功能的正确性。。。(没有函数不习惯。。。)
还是欠练!
筛选法中,估计质数个数有误差,可能是数据太少;所以没有输出所有质数,只是做了统计。
package test;
import java.util.Scanner;
public class test {
public static void main(String[] args) {
/*1、改进定义方法:
*遍历所有奇数,偶数不可能是质数(2除外)
*判断n是否是质数:求n / (2 to sqrt(n)) == 0
* n = sqrt(n) * sqrt(n) ,所以只到sqrt(n)就行
*/
//-----改进定义方法------------------------------
System.out.println("Input n: ");
Scanner scanf = new Scanner(System.in);
int n = scanf.nextInt();
int count = 1; //质数的个数;
System.out.println("2");
boolean isPrime = true;
int j;
//int sqr = (int)(Math.sqrt(n));
for(j=3; j<=n; j+=2){ //3-n中的奇数;
for(int i=2; i<=(int)(Math.sqrt(n)); i++){ //遍历2 to sqr(n)
if(j%i==0 && j!=i){
isPrime = false;
break;
}
}
if(isPrime){
count++;
System.out.println(j);
}
isPrime = true;
}
System.out.println("The count is: ");
System.out.println(count);
} //class ends
}
package Prime;
import java.util.Scanner;
public class IsPrime{
public static void main(String[] args){
/*----2. 埃拉托斯特尼筛法-----------------
* 在[2,n]的序列中,逐步剔除所有质数的倍数;
* 如果剔除后的数列中最大数小于当前素数的平方,则继续剔除;
* Step: 1. 数列[2, 3, 4, 5, ..., 25];
2. 剔除2的倍数,得到[2,3,5,7,...,23,25];
3. 2中数列的最大数是25,小于当前素数2的平方,则继续执行2;
4. 2后面最小的是3,所以3是质数。。。
5. 直到当前剔除素数的平方大于数列中的最后一个数,则完成。
* 构造数组arr,储存[2,n]所有数据;
* 将剔除的数据置0;
* 数组primeNum存储[2,n]所有的质数;
* 确定primeNum的长度:素数定理:确定某个范围内的素数个数:误差15%
len = x/ln(x), x = n;
len = len * 1.15; (一般扩大15%范围)
* 确定下一个素数:最近一个不为0的数;
* 确定当前数列最后一个数:从数组最后开始遍历,第一个不为0的数;
*/
int n = 200;
int[] arr = new int[n-1]; //储存2-n所有数;
//生成arr数组: [2, n];
for(int i=0; i<=n-2; i++){
arr[i] = i+2;
System.out.print(arr[i]+" ");
}
System.out.println();
//剔除倍数:
int curPrime = 2; //当前质数;
int maxOfArr = arr[n-2]; //当前数组中的最大数;
int maxIndex = arr.length-1; //当前最大数的下标
int t = curPrime;
int next = 1; //下一个非0的数的下标;
int count = 0; //需要剔除count次才能得到所有素数;
//剔除素数的倍数;
do{
t = curPrime;
//剔除curPrime的倍数;
for(int i=next; i<=maxIndex; i++){
if(arr[i]%curPrime == 0){
arr[i] = 0;
}
}
//求当前数组的最大数和其下标: 最后一个非0的数;
for(int i=maxIndex; i>=0; i--){
if(arr[i] != 0){
maxIndex = i;
maxOfArr = arr[i];
}
}
//print the result
for(int i=0; i<=n-2; i++){
System.out.print(arr[i]+" ");
}
System.out.println(); //每次剔除都输出;
}while(maxOfArr >= t*t);
}//class ends;
}