日子要回到正轨来,每天两到三小时在学习上。
上次是一道笔试题,输出0-100的质数。
原理是用了嵌套循环+加入标识符,i做外层,j做内层,具体代码为:
class test{
public static void main(String[] args) {
boolean isFlag = true;//标识i是否被j除尽,一旦除尽,修改其值
for (int i = 2; i <= 100 ; i++){//遍历100以内的自然数
for (int j = 2 ; j < i ; j++ ){//j:被i去除
if(i % j == 0){//i被j除尽
isFlag = false;
}
}
if (isFlag == true){
System.out.println(i);
}
//重置isFlag
isFlag = true;
}
}
}
优化点有三个。
第一、在 isFlag = false 后 加入break,优化本身非质数的自然数。
第二、从数学角度出发,质数查询不需要遍历前面的所有数,只需要检查2-根号n之间即可,所以把原嵌套循环里的“j<i改为 j<math.sqrt(i)”
第三、减少每个质数的输出,把原来System.out.println(i)去掉,加入一个count计数器,不需要一个个看,现在直接看个数。
优化后的代码为:
class test1{
public static void main(String[] args) {
boolean isFlag = true;//标识i是否被j除尽,一旦除尽,修改其值
int count = 0 ;
//获取当前时间毫秒数-当前时间距离1970-1-1 00:00:00的时间
long start = System.currentTimeMillis();
for (int i = 2; i <= 100000;i++){//遍历10000以内的自然数
//for (int j = 2 ; j < i ; j++ ){
for (int j = 2 ; j <= Math.sqrt(i) ; j++ ){//j:被i去除
//优化二:对本身是质数的自然数是有效的
if(i % j == 0){//i被j除尽
isFlag = false;
break; //优化一:只对本身非质数的自然数是有效的。
}
}
if (isFlag == true){
//System.out.println(i);
count++;
}
//重置isFlag
isFlag = true;
}
long end = System.currentTimeMillis();//运行结束时的时间
System.out.println("质数的个数为" + count);
System.out.println("所花费的时间为:" + (end - start));//不优化:17240;优化一:5322;优化二:544;优化三:减少每个质数的输出;14
}
}
结果上看,代码优化后效果显著。优秀的算法可以带来质的飞跃。
知识点2:对于break和continue
/*
break 和 continue 关键字的使用
break 适用:switch-case / 循环结构中
作用:结束当前循环
continue 适用:循环结构中 结束当次循环
相同点:break/continue 后关键字无效即关键字后面不能声明执行语句
*/
代码:
class BreakContinueTest{
public static void main(String[] args) {
for (int i = 1; i <= 10 ; i++ ){
if (i % 4 == 0){
continue;//123567910
//break;//123
//后面加输出语句是执行不通的!
}
System.out.println(i);
}
}
}
延伸:带标签的break与continue
先上代码
for (int i = 1;i <= 4 ;i ++ ){
for (int j = 1; j <= 10; j++){
if(j % 4 ==0){
continue;
//结果:123567910\n 123567910\n 123567910\n 123567910
//break;//默认跳出包裹此关键字最近的一层循环。
//结果123\n 123\n 123\n 123
}
System.out.print(j);
}
System.out.println();
}
加标签:
标签的作用是找到指定的位置,确定是内层循环还是外层循环
break加标签,在需要break或continue之前加label:
label:for (int i = 1;i <= 4 ;i ++ ){
for (int j = 1; j <= 10; j++){
if(j % 4 ==0){
break label;
//原来不加label是123/123/123/123
}
System.out.print(j);
}
System.out.println();
}
label:for (int i = 1;i <= 4 ;i ++ ){
for (int j = 1; j <= 10; j++){
if(j % 4 ==0){
continue label;
}
System.out.print(j);
}
System.out.println();
}
//输出的结果是123 123 123 123
//原来的continue结果是123567910\n 123567910\n 123567910\n 123567910