【Java小白图文教程】-04-循环结构

 

精品专题:

01.《C语言从不挂科到高绩点》课程详细笔记

https://blog.csdn.net/yueyehuguang/category_12753294.html?spm=1001.2014.3001.5482

02. 《SpringBoot详细教程》课程详细笔记

https://blog.csdn.net/yueyehuguang/category_12789841.html?spm=1001.2014.3001.5482

03.《SpringBoot电脑商城项目》课程详细笔记

https://blog.csdn.net/yueyehuguang/category_12752883.html?spm=1001.2014.3001.5482

04.《VUE3.0 核心教程》课程详细笔记

https://blog.csdn.net/yueyehuguang/category_12769996.html?spm=1001.2014.3001.5482

================================

||     持续分享系列教程,关注一下不迷路 ||

||         视频教程:小破站:墨轩大楼        ||

================================

3. 循环语句

3.1. 循环概述

在java中程序的执行流程,除了顺序结构,分支结构之外,还有另一种非常常见的结构:循环结构;在对于某些需要反复执行的操作执行时,需要使用到循环,对于某些容器(数组,集合)遍历操作时也需要使用到循环,循环在实际的生产开发环境中应用十分广泛;Java中对于循环的支持,包含以下分类:

  • for循环
  • while循环
  • do..while循环
  • 迭代器:forEach
  • 递归(recursion)

有关循环语句的执行流程:

3.2. for循环

for循环是一种经典循环方式,for循环一般常见于循环次数已知的应用场景中,语法规则:

for(初始值;循环条件;步进){
    //循环体
}
for(int i=1;i<=10;i++){
    int n = (int)(Math.random()*10) + 1;
    System.out.println(n);
}

3.3. while循环

除了for之外,java中对与一些循环次数不定的操作也提供了while循环来实现,while循环的执行次数为0次~N次,语法规则:

while(循环条件){
    //循环体
}
int i = 1;
while(i <= 10){
    System.out.println(i);
    i++;
}

3.4. do...while循环

while循环除了传统写法之外,对于一些特殊的需求还提供了另一种使用方式:do..while;doWhile循环至少会执行一次,最多N次;语法:

do{
    //循环体
}while(循环条件)
do{
    System.out.println(i);
    i++;
}while(i<=10);

3.5. 循环练习

1. 求1+2+3+4+...100=? 考虑临时变量(局部变量)

2. 求 5! = 5*4*3*2*1

3. 打印1000以内的所有偶数
//1000以内的所有偶数
for (int i = 0; i <= 1000 ; i+=2) {
    System.out.print(i+" ");
}
System.out.println();
//请输出1000以内5的倍数
for (int i = 0; i <= 1000 ; i+=5) {
    System.out.print(i+" ");
}
4. 求水仙花数(一个三位数,每一位的立方和都是这个数本身:xyz = x*x*x + y*y*y + z*z*z)
for (int i = 100; i < 1000; i++) {
    int a = i % 10; //个位
    int b = i / 10 % 10; //十位
    int c = i / 100; //百位
    if (a * a * a + b * b * b + c * c * c == i) {
        System.out.println("水仙花数:" + i);
    }
}

4. 扩展:系统输入

通常情况下需要输出数据到控制台我们可以使用System.out(标准输出流)完成,控制台除了可以实现系统输出外同时也支持系统输入System.in(标准输入流);JDK中提供了一个类java.util.Scanner可以实现对标准输入流进行扫描以及读取流中的内容,并且Scanner类还可以将不同的数据扫描读取为不同的数据类型。

Scanner常用方法:

  • next():以空格作为标记读取一段文本内容,返回String类型
  • nextInt():以空格作为标记读取一个整数,返回为int类型
  • nextLine():以换行符作为结束标记,读取一行文本内容,返回String类型
//创建文本扫描对象用于从标准输入流中获取信息(引用数据类型)
Scanner sc = new Scanner(System.in);
//从下一个结束标记(空格)之前扫描一段文本信息(阻塞式)
String s = sc.next();
System.out.println("输入的内容是:"+s);

//读取下一个扫描到的内容并识别为int类型,结束标记为空格
int i = sc.nextInt();
System.out.println("输入的整数是:"+i);

sc.nextLine(); //读取一个空行
System.out.println("================");
//以换行作为结束标记
s = sc.nextLine();
System.out.println("输入的一行内容是:"+s);

思考题

模拟地下城与勇士(DNF)的装备强化过程:

提示1:

  • DNF装备强化在+1~+3 不会失败;
  • +4~+7,失败后物品原有强化等级降低1级;
  • +8~+10,失败后掉3级;
  • 10上11或以上失败就爆了。

提示2:

  • DNF装备强化1~3级,成功率100%
  • DNF装备强化3~4级,成功率95%
  • DNF装备强化4~5级,成功率90%
  • DNF装备强化5~6级,成功率80%
  • DNF装备强化6~7级,成功率75%
  • DNF装备强化7~8级,成功率62.1%
  • DNF装备强化8~9级,成功率53.7%
  • DNF装备强化9~10级,成功率41.4%
  • DNF装备强化10~11级,成功率33.9%
  • DNF装备强化11~12级,成功率28%
  • DNF装备强化12~13级,成功率20.7%
  • DNF装备强化13~14级,成功率17.3%
  • DNF装备强化14~15级,成功率13.6%
  • DNF装备强化15~16级,成功率10.1%

实现流程:

要求输入装备的原始等级,输入1执行强化,根据原始等级以及强化的成功率,显示装备的强化结果

public static void add(int initLevel){
//TODO 实现过程
}

5. 死循环

在使用循环过程中,经常会因为忽略一些关键的实现细节导致程序出现死循环(death loop);死循环往往是因为没为循环设置一个结束条件,或者是设置了一个无法达到的结束条件而导致;

例如:

for(int i = 0;i >= 0;i++){
    System.out.println(i);
}

死循环将会导致程序一直执行,消耗大量的内存空间,影响程序的执行性能,尽量要避免死循环的产生。

另外有些时候使用死循环也能满足一些实际的需求:

for(;;){
    Scanner sc = new Scanner(System.in);
    System.out.print("请输入数字:");
    int n = sc.nextInt();
    System.out.println("您输入的是:"+n);
}

以上的死循环使用while一样可以实现

while(true){
    Scanner sc = new Scanner(System.in);
    System.out.print("请输入数字:");
    int n = sc.nextInt();
    System.out.println("您输入的是:"+n);
}

6. 嵌套循环

6.1. 概述

java中除了支持单层的循环之外,另外也支持在循环中嵌套其他循环,实际开发中应尽可能避免循环的嵌套(会导致内存的开销,影响程序性能);但是有些业务中也必须使用嵌套循环来实现具体功能,例如对二维数组的遍历,对多级菜单的遍历等。

嵌套循环的执行流程图:

for(int i = 1;i<10;i++){
    for(int j = 10;j<20;j++){
        System.out.println(i+"----"+j);
    }
}
  • 练习题:输出一个九九乘法口诀表
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
...

6.2. 嵌套循环练习

  1. 请使用嵌套循环输出以下图形:
*
***
*****
*******
  1. 打印菱形
*
***
*****
*******
*****
***
*
  1. 打印平行四边形
********
********
********
********
********

7. 循环中断

在循环语句正常执行过程中一般没有任何异常情况下,循环会根据结束条件的满足而自然结束,但是某些情况可能需要提前中断循环(不是终止虚拟机);对于这种需求,java中提供了break和continue关键字用于结束(跳过)循环。

例如:输出1000以内,跳过5的倍数输出其他数值。

7.1. continue

continue关键字,在实际使用场景中出现的比较少,一般用在循环内部,用于跳过N次循环中的某一次循环,例如:

for (int i = 0; i < 1000; i++) {
    if(i % 5 == 0){
        //当条件满足时执行continue,跳过本次循环,开始下一次循环
        continue;
    }
    System.out.println(i);
}

以上的运行结果除了5的倍数之外,输出其他的所有小于1000数值

7.2. break

break关键字的使用场景除了在switch语句中用于防止case穿透之外,另外也可以用于循环语句中终止循环,break用在循环中可以结束一层循环。例如:

for (int i = 0; i < 10; i++) {
    for (int j = 10; j < 20; j++) {
        if(j % 6 == 0){
            break;
        }
        System.out.print(i+","+j+" ");
    }
    System.out.println();
}
0,10 0,11 
1,10 1,11 
2,10 2,11 
3,10 3,11 
4,10 4,11 
5,10 5,11 
6,10 6,11 
7,10 7,11 
8,10 8,11 
9,10 9,11

观察以上输出结果,能够直观的发现,当内层循环的变量跟6取余能除尽时,内层循环则直接中断

面试题:continue、break、return关键字的区别?

  • continue主要用于循环语句中,结束一次循环
  • break用于switch语句中防止case穿透;还可以用于循环语句中结束一层循环
  • return用于方法中结束方法,return之后跟随具体的值或者变量用于返回方法的返回值;如果不跟任何内容则表示结束方法

7.3. 循环标记

在某些情况,循环嵌套层次比较多的时候,需要通过break、continue结束(跳过)指定层的循环,可以使用循环标记来完成,循环标记就是为每一个循环语句块添加一个标签,然后在结束时,相关的关键字后面跟上标记就可以实现:

loop1:for (int i = 0; i < 10; i++) {
    loop2:for (int j = 10; j < 20; j++) {
        if(j % 6 == 0){
            break loop1;
        }
        System.out.print(i+","+j+" ");
    }
    System.out.println();
}
System.out.println("程序结束");

以上程序中的loop1和loop2就是循环标签(标签可以自定义:只需要符合标识符的命名规范就可以)

8. 递归(recursion)

8.1. 概述

递归是反复执行代码的另一种方式,区别于传统的循环,原理是在方法层面,对方法自身调用,通过递归可以解决一些循环所解决不了的问题(例如:文件夹的递归遍历,树形菜单的动态展示等),另外使用递归也能解决一些常见的算法问题,例如:斐波拉契数列,汉诺塔等。

递归语法:

修饰符 返回值类型 方法名(){

方法名();

}

在一个方法中对当前方法进行调用即称之为递归:

public void m(){
    system.out.println("方法执行");
    m();
}

注意事项:

如果不为递归方法指定结束条件,则程序将会导致StackOverflowerError出现:

Exception in thread "main" java.lang.StackOverflowError
at com.softeem.day4.recursion.Demo1.sum(Demo1.java:13)
at com.softeem.day4.recursion.Demo1.sum(Demo1.java:13)
at com.softeem.day4.recursion.Demo1.sum(Demo1.java:13)
at com.softeem.day4.recursion.Demo1.sum(Demo1.java:13)
...

8.2. 案例

  • 求1+2+3+4+...+100=?上述问题除了使用传统循环解决之外,使用递归也能轻松实现:
public class Demo1 {

    public static int sum(int n){
        if(n <= 1){
            return 1;
        }else{
            //方法递归调用
            return n + sum(n-1);
        }
    }

    public static void main(String[] args) {
        System.out.println(sum(100)); // 5050
    }
}

原理如下:

  • 求5!
/**
     * 5*4*3*2*1
     *
     * @param n
     * @return
     */
public static int jiecheng(int n) {
if (n == 1) {
    return 1;
} else {
    return jiecheng(n - 1) * n;
}
}

8.3. 思考题

请观察以下的数列,寻找规律

1 1 2 3 5 8 13 21 34 ... n

求n的结果(斐波拉契数列)

public static int fib(int n){
if(n == 1 || n == 2){
    return 1;
}else{
    return fib(n-1) +fib(n - 2);
}
}

练习

  1. 实现汉诺塔(递归实现)

  1. 实现一个动态日历提示:

提示:

1. 平年2月份是28天,闰年2月份是29天;1,3,5,7,8,10,12这几个月是31天,其余的每个月(4,6,9,11)30天

2. 计算从1900年1月到当前月份的上一个月总天数

3. 总天数和7取余之后,余数则为当月前面需要输出的空格(建议使用制表符:tab)数


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听潮阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>