首先要了解什么是质数?
从2开始到这个自然数-1为止,不存在此自然数的约数,这个自然数就是质数
得到这个概念之后,根据要求,遍历即可。
class PrimeNumberTest{
public static void main(String[] args){
//方式一
/*
for(int i = 2;i <= 100;i++){
int number = 0;//记录i的约数的个数(从2到i-1为止)
//判定i是否是质数
for(int j = 2;j <= i - 1;j++){
if(i % j == 0){
number++;
}
}
if(number == 0){
System.out.println(i);
}
}
*/
//方式二
boolean isFlag = true;
for(int i = 2;i <= 100;i++){
//判定i是否是质数
for(int j = 2;j <= i - 1;j++){
if(i % j == 0){
isFlag = false;
}
}
if(flag){
System.out.println(i);
}
//重置isFlag
isFlag = true;
}
}
}
在方式一中:定义了一个number来记录这个自然数 i 从2到 i -1为止的约数的个数,然后有一个if判断number是否还是0,如果是,则这个数就是质数。
在方式二中:定义了一个isFlag的旗帜来判断概述是否被整除过了,也就是在2到 i -1中存在约数,如果有,则赋值为false。在遍历下一个自然数i之前要将isFlag重置为true。
在以上方式效率过于中低下。下面是进行优化后的代码。
不再打印具体的质数,只记录在范围内质数的个数。
class PrimeNumberTest2{
public static void main(String[] args){
//获取当前系统的时间
long start = System.currentTimeMillis();
boolean isFlag = true;
int count = 0;//记录质数的个数
for(int i = 2;i <= 100000;i++){//遍历100000以内的自然数
//判定i是否是质数
for(int j = 2;j < Math.sqrt(i);j++){
if(i % j == 0){
isFlag = false;
break;
}
}
if(isFlag){
count++;
}
//重置isFlag
isFlag = true;
}
//获取当前系统的时间
long end = System.currentTimeMillis();
System.out.println("质数的个数为" + count);//9592
System.out.println("执行所花费的时间为" + (end - start));//6830-->加break:616--->加Math.sqrt(i):6
}
}
优化一:使用break关键字,在这个自然数 i 在整除2到 i -1的时候,一旦整除就终止这次循环,使isFlag赋值为false,跳出内层循环,不再继续检查 i 是否能被其他的数整除
优化二:判断约数的时候,只需要从2到i即可
为什么只需要判断到
√i
?假设你有一个数
i
,它是合数(不是质数)。如果i
可以被某个数a
整除,那么必定存在另一个数b
,使得:
a * b = i
而且,
a
和b
的大小关系是:a <= b
或a >= b
。也就是说,a
和b
至少有一个是小于或等于√i
的。举个例子:
- 如果
i = 36
,那么√36 = 6
。如果36
能被某个数整除,肯定会找到一个小于或等于 6 的数。例如,36 = 6 * 6
。- 如果
i = 100
,那么√100 = 10
,如果100
能被整除,一定能找到一个小于等于 10 的因子,比如100 = 10 * 10
。
以上就是对求出指定范围内的质数的阐述。