令人头痛的循环(;´д`)ゞ
我们在学习循环的时候可能会有点懵,什么是循环?它可以干嘛?我这里为什么要用循环来写这段代码?等问题。
首先我们来讲一下循环可以干嘛
循环是什么?o(′益`)o
在 Java 中,循环是一种控制结构,可以用于重复执行某段代码,知道满足特定的条件。循环结构可以简化代码,减少重复。
这样讲是不是很麻烦,我们可以举一个例子:
加入甲方让我们写一个功能,要求输出 100 个 hello world。如果没有循环的话,我们的代码就是这样的
system.out.println("hello world");
system.out.println("hello world");
system.out.println("hello world");
system.out.println("hello world");
system.out.println("hello world");
....
//以此类推
但是有了循环的话,我们可以减少我们的代码量,而且也可以方便我们在后期对于代码的维护和修改。
for(int i = 0 ; i<=100 ; i++)
{
system.out.println("hello world");
}
这样的话,如果后面甲方说,”我不想要 hello world 的了,我想要别的东西,比如”你好“。那这样的话,我们修改代码一的话就会一段一段的删改删改,很麻烦。而代码二的话,我们只需要修改一次就可以解决全部的问题了
那循环是如何判断的呢?或者说,循环是如何运行的
循环可以干嘛?(=′ー`)
在上文中,我们知道了循环是什么东西,我们现在就来解决第二个问题,循环可以干嘛?
其实循环我感觉是一种思想,在不同的场景,循环有不同的作用,比如说:
- 遍历数组或集合
- 重复操作
- 条件检查和递归
- 等等
代码 1
在重复操作中,循环就只是单单循环这段 print 代码。如果说在递归中,就是在检测参数是否到达了你规定的条件。还有很多其他的思路,得结合具体的实操。
现在我们拿一个具体的例子来学习(这里用的是一个
import java.util.Scanner;
public class machine
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in); //创建一个输入
System.out.println("请投币:"); //提示用户请输入
int amount = in.nextInt();
if(amount >= 10)
{
//打印车票
System.out.println("Java铁路专线/10元");
//找零
System.out.println("找零:" + (amount-10));
}
}
}
/*我们会如何思考优化呢?
1. 首先他得有一个循环,我可以买完一张票后,不退出,或者说,我第一次投入的钱不足5块,我可以多投几次来满足这个票钱
2. 有了循环之后,就需要一个退出循环的参数,就好比如我买完票后,你不能自动退出买票界面,需要我自己去点击一下关闭键。
3. 既然我可以多次投入钱的话,那么之前的参数就不能再用了,我需要一个新的参数来满足我投入的钱的和。
*/
import java.util.Scanner;
public class machine
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in); //创建一个输入
int banlanc = 0;
while (true)
{
System.out.println("请投币:"); //提示用户请输入
int amount = in.nextInt();
banlanc = banlanc + amount;
if (banlanc >= 10)
{
//打印车票
System.out.println("Java铁路专线/10元");
//找零
System.out.println("找零:" + (banlanc - 10));
banlanc = 0; //找零之后,我们投入的钱数得归0。
System.out.println("如果想要退出请输入-1");
int quit = in.nextInt();
if(quit == -1)
{
break;
}
}
}
}
}
import java.util.Scanner;
public class TicketMachine {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int balance = 0;
while (true) {
System.out.println("请投币:");
int amount = scanner.nextInt();
balance += amount;
if (balance >= 10) {
// 打印车票
System.out.println("Java铁路专线/10元");
// 找零
int change = balance - 10;
System.out.printf("找零:%d%n", change);
balance = 0; // 找零之后,我们投入的钱数得归0。
System.out.println("如果想要退出请输入-1");
int quit = scanner.nextInt();
if (quit == -1) {
break;
}
} else {
System.out.println("余额不足,请继续投币!");
}
}
}
}
我的代码思路:
这个project我是这样思考的:
首先我得有一个变量来判断我的钱是否足够买票,如果不够买票的话,程序就退出(暂且的)
然后在用我们投入的钱减去10,用来找零
然后是优化思路:
- 首先他得有一个循环,我可以买完一张票后,不退出,或者说,我第一次投入的钱不足5块,我可以多投几次来满足这个票钱
- 有了循环之后,就需要一个退出循环的参数,就好比如我买完票后,你不能自动退出买票界面,需要我自己去点击一下关闭键。
- 既然我可以多次投入钱的话,那么之前的参数就不能再用了,我需要一个新的参数来满足我投入的钱的和。
然后这个是gpt的优化思路:
- 简化循环逻辑:将循环条件从 while (true) 改为一个明确的条件 !exit。
- 减少对象创建:在循环外面创建一个 Scanner 对象,并且只在需要时使用它。
- 合理处理余额不足情况:当余额不足时,提示用户继续投币,而不是直接退出程序。
- 优化找零逻辑:在找零时,将余额减去 10,然后打印找零金额。
- 使用格式化输出:使用 System.out.printf() 来打印车票和找零金额,可以使输出更美观和易读。
- 添加退出条件:在循环中添加一个退出条件,让用户可以选择退出程序
代码 2(课程代码)
这个程序是让我们数数字,就好比如
输入:123 输出:3 位数
这个程序我要如何来写?有没有什么大致的框架。
我的思路:
你看 123 这个数,我们如果用除法的话是不是这样的
123/10 -> 12
12/10 -> 1
1/10 -> 0
那么我们可以来用一个循环来一直做这个操作,直到为0
然后再用一个count参数来记下来一共执行了几次循环,那他就是一个几位数
import java.util.Scanner;
public class Count_numbers
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int count = 0;
System.out.println("请输入一个数");
int input = in.nextInt(); //用于输入我们输入的数字
while (input != 0) //如果等于0的话,就相当于这个数已经被除完了。
{
input = input / 10; //核心思路
count++; //用来计算位数的
}
System.out.println("这是一个"+count+"位数");
}
}
import java.util.Scanner;
public class Count_numbers {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入一个数");
int input = in.nextInt();
int count = 0;
while (input != 0) {
input /= 10; // 这里可以直接使用 /= 运算符
count++;
}
System.out.println("这是一个" + count + "位数");
}
}
循环的分类o(〃'▽'〃)o
while
我们把 while 循环说的直白一点就是,当条件满足的时候,不断地重复循环体内的语句
条件成立是循环继续的条件
格式是这样的
while( 布尔表达式 ) {
//循环内容
}
只要布尔表达式为 true,循环就会一直执行下去。
do while
对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。
或者说:
在进入代码的时候不做检查,而是执行完一轮循环体的代码之后,再来检查循环是否满足条件,满足则进行下一轮循环,不满足则执行下面语句。
do {
//代码语句
}while(布尔表达式);
注意:布尔表达式在循环体的后面,所以语句块在检测布尔表达式之前已经执行了。 如果布尔表达式的值为 true,则语句块一直执行,直到布尔表达式的值为 false。
for
来了,最最常用且最最重要的一个循环,for 循环。很多人在这里都会不懂
首先我们来学习一下 for 循环的格式
虽然所有循环结构都可以用 while 或者 do...while表示,但 Java 提供了另一种语句 —— for 循环,使一些循环结构变得更加简单。
for循环执行的次数是在执行前就确定的。语法格式如下:
for(初始动作; 布尔表达式; 自增或自减(每轮的动作))
{
//代码语句
}
关于 for 循环有以下几点说明:
- 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
- 然后,检测布尔表达式的值。如果为 true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
- 执行一次循环后,更新循环控制变量。
- 再次检测布尔表达式。循环执行上面的过程。
这种书面语,估计大家听着业不知道 for 可以干嘛,我们直接上一个非常简单的例子
这个例子是阶乘,要求是这样的
n!=1x2x3x4x5x...
写一个程序,让用户输入 n,然后计算出 n!
思路:
首先,我们思考这个程序的时候我们要围绕着 n!来想。
最开始,我们需要定义一个变量把,这个变量用来储存我们用来算阶乘的数(变量:n)
然后我们有了输入的数之后,我们需要想怎么求这个数的阶乘
那我们需要用一个循环,来依次乘我们输入的这个数的下一个数,就好像是我们输入的 5,然后下一个数就是乘以 4 这样的,那这样看来其实 for 循环是最好的。
然后我们在 for 循环体内在写入阶乘函数就可以了
import java.util.Scanner;
public class factorial
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("请输入一个数");
int n = in.nextInt(); //我们输入的阶乘n
int result = 1; //用来保存第一位数1;
for(int i = 1;i<=n;i++) //这里我们不能让i=0,因为i要是等于0的话,整个阶乘都会变成0
{
result *= i; //阶乘函数
}
System.out.println("这个数的阶乘是"+result);
}
}
我们可以发现在这个程序中,for 循环的功能主要是用来计数用的,或者说,我们来判断我们的 i 什么时候大于 n,然后我们就结束这个循环。
三个循环的总结
- FOR:如果有固定的次数,我们就用 for 循环
- do-while:如果必须执行一次的话,我们就用 do-while
- while:其他情况就用 while
循环高级篇
复合赋值
这章有点绕,只要讲的是这些东西
- i++
- ++i
- i--
- --i
- +=
- -=
- *=
- /=
这类东西
这个板块我们讲的是+=这类问题:
在 Java 中,我们可以把 a = a + 1 这样的式子转换成 a += 1
以此类推,什么-=,*=,/=都可以这样转换,但是注意一下
a += b+1 这种,我们需要知道,他拆开是这样的 a = a +(b+1)
这个板块我们讲 i++这类问题
这个点很绕,但是我尽量讲清楚。
首先我们需要了解到一点,在 Java 中,i = i+1 可以变成 i++
但是但是,++i 也可以是 i = i +1
诶,这两个有什么区别吗?(○` 3′○)
当然有,假如说 i=6
a = i++
a = ++i
就先那这两个例子来说
a = i++的话,我们在进行完运算之后,a=6,i=7
a = ++i 的话,我们在进行完运算之后,a=7,i=7
我们可以把 i++理解为后缀,++i 理解为前缀,那么我们 a 在前缀运算的情况下,a 要等于 i 这个值
a 在后缀的情况下,a 要等于 i+1 后的值
直白点就是,a = i++的情况下,a 要等于 i,然后 i 再去做 i++运算
如果 a = ++i 的话,那么 a 就等于 i+1 的那个值,然后 i +1.
i 不管是前缀还是后缀,都要做 i+1 运算。
当然 i--和--i 也是一样的思路。
但是但是,又有一个新的问题了,你觉得什么时候用 i++,什么时候用++i 呢?
循环控制
这个主要讲的是这个
- break
- continue
- return
首先我们讲讲 break
- 循环结构结束不等于方法结束,for 循环结构体后面的语句还会正常运行
- break 只是终止当层循环:
- 如果在内层想要终止外层循环:可以给外层循环取一个别名,然后使用
break 名字;
结束外层循环。
ps:
class BreakTest {
public static void main(String[] args) {
test:for(int i = 0; i <= 5; i++) {
System.out.println(i);
for(int j = 0; j <= 5; j++) {
if(j == 3) {
break test;
}
}
}
}
}
然后是 continue,这个主要是跳出当层当次循环,然后继续下一次循环
最后是 return,在循环中使用时结束方法,表示结束当前的方法
注意:break、coutinue、return,后面都不能写语句。编译会报错:访问不到
循环嵌套
okok,到了我觉得循环中最最难的地方了,我感觉我光讲概念的话,肯定我也蒙了,你也蒙了,我们还是结合例子,边看例子,边学概念吧
我们本章那素数来举例子
说到素数,首先,什么是素数?
概念:素数(Prime Number)是指一个大于 1 的自然数,除了 1 和它本身之外,没有其他正整数能整除它。
说的直白点就是,一个数只有两个因数,1 和他自己,就称之为素数。
就像是 2.3.5.7.9.11.13...这样的数
那我们要如何写代码呢?
代码思路:
首先我们得有一个输入,用来保存我们想要鉴定的数。
Scanner in = new Scanner(System.in);
int isPrime = in.nextInt();
然后我们来思考一下如何判断这个数是否为素数
根据概念来说的话,只有 1 和他本身可以整除他自己的话,如果 isPrime %= i 为 0 的话,就是不是素数了(i 在 for 循环中定义的,i=2)
for(int i = 2 ; i < isPrime ; i++)
{
if(isPrime % i == 0)
{
System.out.println("不是素数");
break;
}
}
整体代码:
import java.util.Scanner;
public class Prime
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("请输入一个数");
int num = in.nextInt();
for(int i = 2 ; i < num ; i++)
{
if(num % i == 0) //如果可以被2整除的话,那么证明他还有另外一个因数,所以不是素数
{
System.out.println("不是素数");
break;
}
}
if (num > 1)
{
System.out.println("是素数");
}
else
{
System.out.println("error");
}
}
}
好了,我们现在知道了素数的 code 如何写,那让你写一个 100 以内的素数呢?
我们应该如何去思考这个程序呢?
我们在思考这个程序之前,我们要知道,循环嵌套的流程是什么?除了 for 循环嵌套,while 和 do...while 循环可以嵌套吗?
首先我们讲一下 for 循环的嵌套的流程图:
我们要如何理解?
我们现在写一个 for 循环嵌套的框架
for() //外层循环
{
for() //内层循环
{
//代码块
}
}
外层的 for 循环语句是控制内层 for 循环语句的次数的
内层 for 循环语句是用来控制程序的逻辑的
我们可以先拿一个*型长方形来举例子
首先我们先看到要求:
输出这个图形
* * * * * * *
* * * * * * *
* * * * * * *
* * * * * * *
那我们根据要求我们可以怎么写呢?
我们根据 for 循环嵌套来思考的话,首先我们需要定义两个变量来控制循环吧
int i,j;
然后我们回归程序来思考,我们需要如何写可以输出第一行的这个*号呢?
我们是不是可以用一个 for 循环,然后我们让 i 或者 j 这个参数<=要求上的星号数量,并且 i 或者 j 每一次自增一个。
for(j=0;j<=7;i++)
{
System.out.print("* ");
}
我们是不是这样就可以输出第一段了,好,现在我们输出了第一行的 *号,我们是不是可以这样去思考,我们再用一个循环,把这个输出 *号的这段循环给循环几遍。有点绕啊,建议多读几遍。
那这就是循环嵌套的思路了
for(i=0;i<=3;i++)
{
for(j=0;j<=6;j++)
{
System.out.print("* ");
}
System.out.println();
}
然后输出出来就是要求了。
既然了解了什么是循环嵌套了,那我们可以回到最初的那个问题了
写一个 100 以内的素数呢?
首先我们得知道素数的程序咋写吧
import java.util.Scanner;
public class Prime
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("请输入一个数");
int num = in.nextInt();
for(int i = 2 ; i < num ; i++)
{
if(num % i == 0)
{
System.out.println("不是素数");
break;
}
}
if (num > 1)
{
System.out.println("是素数");
}
else
{
System.out.println("error");
}
}
}
我们知道他的思路了,我们就可以对其进行改进了。
按照我的习惯,我可能还是会先写内层循环
//内层循环
for (int j = 2;j < i; j++)
{
if( i % j == 0) //素数的原理
{
isPrime = false;
break;
}
}
这个主要是用来判断是不是素数的,如果余数为 0 的话,就不是素数了(这里的 isprime=false 我们等会会讲)。
写完内层以后,我们就得写外层,外层的思路就是我们得用一个 i 遍历 2-100 之间的数
for(int i = 2; i<=100; i++) //遍历2到100的每一个数字
{
boolean isPrime = true;
//接入内层循环
}
ok,这里我们遇到了一个 Boolean isprime 了,我是这样想的,我们最开始定义一个数他是素数,如果满足了内层循环的判断的话,我们再将 isprime 变成 false。
ok,我们现在内外层结合一下
for(int i = 2; i<=100; i++) //遍历2到100的每一个数字
{
boolean isPrime = true;
//内层循环
for (int j = 2;j < i; j++)
{
if( i % j == 0) //素数的原理
{
isPrime = false;
break;
}
}
}
大概的一个轮廓都有了,然后我们要回到要求了,我们需要输出这些素数,那我们是不是得再来一个 sout 啊。
for(int i = 2; i<=100; i++) //遍历2到100的每一个数字
{
boolean isPrime = true;
//内层循环
for (int j = 2;j < i; j++)
{
if( i % j == 0) //素数的原理
{
isPrime = false;
break;
}
}
if(isPrime)
{
System.out.println(i);
}
}
我们直接用一个 if 来检测 isprime,isprime 为 true 的话,就是素数,然后输出出来。ok,这样看来我们循环嵌套也可以结束了。
总结
这个专项主要是跟着翁恺老师学习的一个笔记,本人只是一个萌新小白,如果写的有问题的话,也请帮忙指出来。