文章目录
<a href="#Java100_6">Java输出100以内的质数</a> <a href="#_39">重点:<代码的优化></a>
<a href="#P1currenttimemillis_41">P1:currenttimemillis方法计算运行时间</a> <a href="#p2_47">p2:优化一(针对非质数)</a> <a href="#p3Java__Mathsqrt_88">p3:Java 中 Math.sqrt()方法(开平方)</a> <a href="#p4_102">p4:优化二(针对质数)</a> <a href="#P5_146">P5:优化后最终结果</a>
⭕️前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家(点击跳转到网站)⭕️
Java输出100以内的质数
质数:素数,只能被1和他本身整除的自然数(最小质数为2)
答案代码:
package qiantaoxunhuan;
public class E {
public static void main(String[] args) {
//boolean isFlag=true;//标识i是否被j除尽,一旦除尽,修改其值
for (int i = 2; i <=100 ; i++) {//遍历100以内自然数
boolean isFlag=true;//标识i是否被j除尽,一旦除尽,修改其值
for (int j = 2; j <i ; j++) {
if (i%j==0){//i被j除尽
isFlag=false;
}
}
if (isFlag==true){
System.out.println(i);
}
//重置isFlage
//isFlag=true;
}
}
}
注解:这里的第7行代码,对isFlage的定义可以放在循环体外面,然后在打印数据之后进行一次重置,这样虽然代码复杂一点,但节约了内存
重点:<代码的优化>
P1:currenttimemillis方法计算运行时间
描述:public static long currentTimeMillis()返回当前时间(以毫秒为单位)。 请注意,虽然返回值的时间单位为毫秒,但该值的粒度取决于底层操作系统,并且可能较大。 例如,许多操作系统以几十毫秒为单位测量时间。
有关“计算机时间”和协调世界时间(UTC)之间可能出现的轻微差异的讨论,请参阅类别Date的说明。
在1970年1月1日UTC之间的当前时间和午夜之间的差异,以毫秒为单位。
p2:优化一(针对非质数)
package qiantaoxunhuan;
public class E2 {
public static void main(String[] args) {
boolean isFlag=true;
long start = System.currentTimeMillis();//获取当前时间距离1970年1月1日UTC的毫秒数
for (int i = 2; i <=100000; i++) {
for (int j = 2; j <i; j++) {
if (i%j==0){
isFlag=false;
break;//优化一:只对本身非质数的自然是是有效的
}
}
if (isFlag==true){
System.out.println(i);
}
isFlag=true;//重置isFlage
}
long end = System.currentTimeMillis();//获取当前时间距离1970年1月1日UTC的毫秒数
System.out.println("所花费的时间为"+(end-start));
}
}
注解:在代码中的if判断语句位置,当判断出被除尽之后,加上break,这样的话本身非质数的自然数被判定出来之后,便不在进行后续的计算,这里将数据基数改为10万,而不是100了,不然优化之后的时间差不明显(如下)
优化前
优化后
这里不难看出,当数据基数较大时,优化后比优化前时间少很多很多
p3:Java 中 Math.sqrt()方法(开平方)
描述:public static double sqrt(double a)返回double值正确舍入的正平方根。 特殊情况:
如果参数为NaN或小于零,则结果为NaN。 如果参数为无穷大,则结果为正无穷大。 如果参数为正零或负零,则结果与参数相同。
否则,结果是double最接近参数值的真实数学平方根值。
参数
a - 一个值。
结果
正平方根a 。 如果参数为NaN或小于零,则结果为NaN。
p4:优化二(针对质数)
package qiantaoxunhuan;
public class E2 {
public static void main(String[] args) {
boolean isFlag=true;
long start = System.currentTimeMillis();//获取当前时间距离1970年1月1日UTC的毫秒数
for (int i = 2; i <=100000; i++) {
for (int j = 2; j <=Math.sqrt(i); j++) {//优化二:判断一个数是否是素数,只要除到那个数开根号就够了
if (i%j==0){
isFlag=false;
// break;//优化一:只对本身非质数的自然是是有效的
}
}
if (isFlag==true){
System.out.println(i);
}
isFlag=true;//重置isFlage
}
long end = System.currentTimeMillis();//获取当前时间距离1970年1月1日UTC的毫秒数
System.out.println("所花费的时间为"+(end-start));
}
}
问题:判断一个数是否是素数,为什么只要除到根号那个数就够了?
答:一个数n如果不是素数那么一定存在若干因子(不少于2个),
假设最小的因子是p,那么p*p <= n
所以得: p < = 根 号 n
结论:
这里就不截图了,数据大概如下(这里便于观察差距,数据仍然为10万,break的优化注释掉了)
优化前大概:13005
优化后大概:190
不难看出,这次的优化,时间节省上已经完全不是一个量级
P5:优化后最终结果
package qiantaoxunhuan;
public class E2 {
public static void main(String[] args) {
boolean isFlag=true;
long start = System.currentTimeMillis();//获取当前时间距离1970年1月1日UTC的毫秒数
for (int i = 2; i <=100000; i++) {
for (int j = 2; j <=Math.sqrt(i); j++) {//优化二:判断一个数是否是素数,只要除到那个数开根号就够了
if (i%j==0){
isFlag=false;
break;//优化一:只对本身非质数的自然是是有效的
}
}
if (isFlag==true){
System.out.println(i);
}
isFlag=true;//重置isFlage
}
long end = System.currentTimeMillis();//获取当前时间距离1970年1月1日UTC的毫秒数
System.out.println("所花费的时间为"+(end-start));
}
}
运行结果:
总结论:综上所述可以看见质数输出的算法优化之后,效率提高了之后完全不是一个量级