进阶的java循环

Java三种循环结构

第一种:  While(条件){循环体}

第二种: for(循环变量的赋值;循环变量循环条件  ;循环变量增加量){循环体}

第三种: do {循环体} while(条件)

退出:break退出循环

第五个: 打印九九乘法表

******优化商品价格猜猜猜******

 这里使用的类型是float类型, 价格要产生两位的小数

只能产生整数,Math.round是四舍五入

plan_price=Math.round(Math.random()*1000+1000);

注意:float类型数据注意的地方

(1)float类型在定义赋初值的时候,后面跟上一个f

float plan_price=0.00f;

 (2)一般的float类型需要格式化,printf或者String.format

 System.out.printf("%.3f",d);

或者String.format(“%.3f”,d)

这里.3f表示小数位数是3位,这里的3可以换成0,换成0就没有小数,默认去掉后面的位数使用四舍五入的方法。

(3)float 由于后台存储精度的问题,一般做加减乘除运算不准确。

double add1=0.1f;

double add2=0.2f;

System.out.println(add1+add2);

System.out.println(add1*add2);
由于精度的原因,后台运算加减乘除是不准确的。
(4)对于精度高的数字,不要轻易做比较运算
 public class test_compare {

    public static void main(String[] args) {

        double compare1=1f;

        //小数后的数值超过7位(不包括7),四舍五入的数值与某个值很接近,直接判定相等。

        double compare2=0.9999999f;

        //如果小数点后89,就容易造成精度上的相等。

        double compare3=0.99999999f;

        System.out.println(compare1==compare2);

        System.out.println(compare1==compare3);

    }

}

(5)由于精度的问题,注意对float和double的转换,不要做把float类型转成double.

public class test_trans {

    public static void main(String[] args) {

        float num=1.1f;

        double result=(double)num;

        System.out.println(result);

    }

}

 转成double后,如果不对小数点位数做限制,后面由于精度的原因,两个数值不相等.

注意:转化时尽量小数点位数做限制

(6)++运算和—运算也不要放在double类型上

    

 public class test_加加 {

    public static void main(String[] args) {

        double s1=0.8376029181222121;

        for(int i=0;i<10;i++){

            System.out.println(s1);

            s1++;

        }

    }

}

运算结果不是简单的加1,后面的数字也有改变,限定小数位数.

总结:对于double或者float类型,不要轻易做转化和运算,做转化和运算前做小数位数的限定.

输入的数据需要匹配用户输入的内容,用户输入不能有字母符号,搜索正则表达式匹配小数

^[0-9]+(.[0-9]{1,2})?$

正则表达式

^表示定义数据形式的开始

$表示定义数据形式的结束

[0-9]表示0-9数字出现任意一个[a-z]a-z任意一个出现即可

后面+号可以有多个,至少1个

后面还可以跟*号,表示可以没有,至少0个   

()是可选项

.小数点必须有个点

[0-9]也是0-9任意一个

{1,2}大括号里面的1,2,小数点后面的位数只能1位或者是2位,如果对于数字限定位数,就用大括号

自己练习(简易)

手机号(11位,数字

手机号第一个数字1

^1[3,5,6,7,8,9][0-9]{9}$     

 正则表达式只用于字符串,可以matches 方法进行匹配

tmp_user_price.matches("^[0-9]+(.[0-9]{1,2})?$")

 

这里我们写while方法和官方class文件中的内容做对比

第一种:while方法

String tmp_user_price=scanner.next();

//注意while里面匹配小数的正则,不匹配取非(!)

while(!tmp_user_price.matches("^[0-9]+(.[0-9]{1,2})?$")){

    System.out.println("你输入的价格有问题,请检查输入价格:");

    tmp_user_price=scanner.next();

}

 第二种:for的写法

for(tmp_user_price = scanner.next(); !tmp_user_price.matches("^[0-9]+(.[0-9]{1,2})?$"); tmp_user_price = scanner.next()) {

    System.out.println("你输入的价格有问题,请检查输入价格:");

}

这里基本我们这里的while,在class字节文件中都转化成了for

循环的思路:

把需要循环放在循环体里,确定好循环的条件,确定循环次数使用for,不确定循环次数使用while,可以效仿class文件,所有的循环都用for解决

While循环里套用另个一个while,或者是for循环中套用另外一个for,这就是循环嵌套.

这里我们写一个switch

  switch(user_choice){

            case "1":

                //只能产生整数,不需要round,经过round计算后是double类型,当前plan_price也不是两位小数

                //需要用到格式化的方法,先把Math.random()*1000+1000变成字符串,字符串转化成%f,保留两位小数

                //这里先产生一个临时的字符串,可以调用String.format,使用%.2f

                String tmp_price=String.format("%.2f",Math.random()*1000+1000);

                //之后再把tmp_price转化成float类型,不同类型之间转换调用类型的大写.parse类型

                plan_price=Float.parseFloat(tmp_price);

//                System.out.println(plan_price);

                break;

            case "2":

                //先定义一个临时变量,格式化字符串两位小数

                tmp_price=String.format("%.2f",Math.random()*99+1);

                //再使用Float.parseFloat不同类型之间转化方法转化成float类型

                plan_price=Float.parseFloat(tmp_price);

//                System.out.println(plan_price);

                break;

            default:

                //先定义一个临时变量,格式化字符串两位小数

                tmp_price=String.format("%.2f",Math.random()*10000);

                //再使用Float.parseFloat不同类型之间转化方法转化成float类型

                plan_price=Float.parseFloat(tmp_price);

        }

字节文件添加一个byte的中间变量

byte var6 = -1;

switch(user_choice.hashCode()) {

case 49:

    if (user_choice.equals("1")) {

        var6 = 0;

    }

    break;

case 50:

    if (user_choice.equals("2")) {

        var6 = 1;

    }

}

给这个中间变量0和-1,然后根据中间变量做代码中的逻辑

switch(var6) {

case 0:

    tmp_price = String.format("%.2f", Math.random() * 1000.0D + 1000.0D);

    plan_price = Float.parseFloat(tmp_price);

    break;

case 1:

    tmp_price = String.format("%.2f", Math.random() * 99.0D + 1.0D);

    plan_price = Float.parseFloat(tmp_price);

    break;

default:

    tmp_price = String.format("%.2f", Math.random() * 10000.0D);

    plan_price = Float.parseFloat(tmp_price);

}

        

 

精典程序:九九乘法法

思想:用循环解决各种形状问题

(1)

*

* *

* * *

(2)

       *

      * *

     * * * *

   * * * * * *

(3)九九乘法表的形状

1*1=1

1*2=2  2*2=4

1*3=3  2*3=6  3*3=9

思想:

  1. 这里面有两个数相乘,产生两个数

1-9乘以1-9,这里未知数是两个,这两个数字交叉相叉。

凡是思想中存在两值交叉的现象,就是双重循环

两个交叉相乘属于笛卡尔积

构建出来

调整结构

分出行和列的关系

打印的几种函数:

Println实现的效果:每打印一行,就换行,

Print实现的效果:不换行

Printf 按某种格式输出,使用format格式化的形式输出,不换行

打印过程中的转义字符

需要代表某些特殊意义的字符,称为转义字符

比如两个数据之间长空白(8个) 制表符   \t

还比如 \n 实现换行

最麻烦的””  ,在java编程中,单引号和双引号都有特殊意义,双引号内部输出双引号,可以使用转义\,加上一个引号  

System.out.print("\"");
如果输出斜杠,使用两个斜杠.
System.out.print("\\");
 

 原来

1*1=1  1*2=2 1*3=3  行,转成列  

 第一个乘数是i,第二个乘数是j

根据打印的结果,j<=i的就打印结果,j>i的就不打印结果

代码如下:

public class test_nine_nine_multi {

    public static void main(String[] args) {

        //产生笛卡尔积相乘的两个数字,这就是双重循环

        for(int i=1;i<10;i++){

            for(int j=1;j<10;j++){

                //满足条件的打印,根据去掉部分的特点,j>i的不打印,只打印j<=i

                //注意第一个乘数是i,第二个乘数是j,调用位置相当于把行列调换

                if(j<=i){

                    System.out.print(j+"*"+i+"="+i*j+"\t");

                }

            }

            //每打完9个数字,换个行,第一重循环结束打印换行

            System.out.println();

        }

    }

}

 正向思路:

只要j>i就使用break退出

public class test_nine_nine_multi1 {

    public static void main(String[] args) {

        //产生笛卡尔积相乘的两个数字,这就是双重循环

        for(int i=1;i<10;i++){

            for(int j=1;j<10;j++){

                //满足条件的打印,根据去掉部分的特点,j>i的不打印,后面的都不打印,节省循环,可以直接退出循环

                if(j>i){

                    //这里break退出,只要打印列数>行数,后面就不循环了,这种方法循环次数会少一些

                    break;

                }

                //注意第一个乘数是i,第二个乘数是j,调用位置相当于把行列调换

                System.out.print(j+"*"+i+"="+i*j+"\t");



            }

            //每打完9个数字,换个行,第一重循环结束打印换行

            System.out.println();

        }

    }

}

这个程序比上一次程序循环次数减少.

现在再改,如果j==i,打印完当次结果,就没有必要再进入循环体,再进入循环体也就是判断退出,把j==i条件放在打印的后面.

最后再优化,把j==i后面的循环都不进行操作,这种量级减少循环

public class test_nine_nine_multi2 {

    public static void main(String[] args) {

        //产生笛卡尔积相乘的两个数字,这就是双重循环

        for(int i=1;i<10;i++){

            for(int j=1;j<10;j++){

                //注意第一个乘数是i,第二个乘数是j,调用位置相当于把行列调换

                System.out.print(j+"*"+i+"="+i*j+"\t");

                //满足条件的打印,根据去掉部分的特点,j=i的打印结束,后面的循环没有必要了

                if(j==i){

                    //这里break退出,后面的循环完全没有必要

                    break;

                }

            }

            //每打完9个数字,换个行,第一重循环结束打印换行

            System.out.println();

        }

    }

}

对比class字节的处理

for(int i = 1; i < 10; ++i) {

    for(int j = 1; j < 10 && j <= i; ++j) {

        System.out.print(j + "*" + i + "=" + i * j + "\t");

    }



    System.out.println();

}

 这种比上面的代码还科学

算法的大O

第一种双重循环,达到某一条件打印: O(n平方 )

第二种双重循环:<o的平方结果的一半

第三种双重循环,比第二重循环少了外层量级的循环次数

在多重循环中,考虑内层循环是否可以再量级减少循环次数.

break退出,退出一层循环,改变当前层的循环次数

continue退出:退出当前循环的次数,继续下次循环,不改变总体的循环次数

共同点:都不执行循环体中后面的语句

不同点:continue结束当前,break结束本层循环

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值