循环就像城市交通管理系统,不同类型的循环好比各种交通指挥方式:for循环像定时红绿灯,while循环像交警手动指挥,do-while则像必须至少放行一次的应急通道。
想象一个自助餐厅的运营场景:
- for循环:像固定菜品的取餐区,知道确切数量(比如10道热菜)
- while循环:像现做档口,只要还有客人排队就继续供应
- do-while循环:像必须至少询问一次的会员卡办理
这种综合应用场景,最能体现循环在实际开发中的价值。
案例解析
智能点餐系统
编写程序,结合多种循环实现餐厅管理系统。
# 源文件保存为“SmartRestaurant.java”
import java.util.Scanner;
public class SmartRestaurant {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] menu = {"红烧肉", "清蒸鱼", "宫保鸡丁", "麻婆豆腐"};
int[] prices = {58, 88, 42, 36};
int[] orders = new int[menu.length];
int total = 0;
// for循环展示固定菜单
System.out.println("=== 今日菜单 ===");
for(int i=0; i<menu.length; i++) {
System.out.printf("%d. %s %d元\n", i+1, menu[i], prices[i]);
}
// while循环处理点餐
boolean ordering = true;
while(ordering) {
System.out.print("\n请输入菜品编号(0结束):");
int choice = scanner.nextInt();
if(choice == 0) {
ordering = false;
} else if(choice > 0 && choice <= menu.length) {
System.out.print("请输入份数:");
int quantity = scanner.nextInt();
orders[choice-1] += quantity;
total += prices[choice-1] * quantity;
} else {
System.out.println("输入无效!");
}
}
// do-while循环确认支付
boolean paid = false;
do {
System.out.printf("\n总计:%d元,确认支付?(1确认/0取消)", total);
int confirm = scanner.nextInt();
if(confirm == 1) {
paid = true;
System.out.println("支付成功!");
} else if(confirm == 0) {
System.out.println("已取消订单");
break;
}
} while(!paid);
scanner.close();
}
}
运行示例: 依次输入菜品变化、数量等信息。
=== 今日菜单 ===
- 红烧肉 58元
- 清蒸鱼 88元
- 宫保鸡丁 42元
- 麻婆豆腐 36元
请输入菜品编号(0结束):2 请输入份数:1
请输入菜品编号(0结束):4 请输入份数:2
请输入菜品编号(0结束):0
总计:160元,确认支付?(1确认/0取消)1 支付成功!
代码特点
- for循环处理已知数量的菜单展示
- while循环灵活处理不确定数量的点餐
- do-while确保至少执行一次的支付确认
- 数组存储菜单和订单信息
这个案例展示了如何根据场景特点选择合适的循环结构,就像交通管理员根据路况选择指挥方式。
素数筛法
编写一个程序,应用多种循环的优化素数筛法。
# 源文件保存为“PrimeSieve.java”
public class PrimeSieve {
public static void main(String[] args) {
int n = 100;
boolean[] isPrime = new boolean[n+1];
// 初始化所有数为素数
for(int i=2; i<=n; i++) {
isPrime[i] = true;
}
// 筛除非素数
for(int i=2; i*i<=n; i++) {
if(isPrime[i]) {
for(int j=i*i; j<=n; j+=i) {
isPrime[j] = false;
}
}
}
// 输出结果
System.out.println("100以内的素数:");
int count = 0;
for(int i=2; i<=n; i++) {
if(isPrime[i]) {
System.out.print(i + " ");
if(++count % 10 == 0) {
System.out.println();
}
}
}
}
}
运行结果
100以内的素数: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
算法精要
- 第一个for循环进行初始化
- 第二个for循环结合while特性(i*i<=n)
- 内层for循环标记非素数
- 最后for循环输出结果并控制格式
这种综合应用展示了循环结构在算法中的强大威力,就像交通系统协同工作提升整体效率。
常见错误和解决方案
死循环陷阱
while(total > 0) { // 条件永远不会变
System.out.println("Processing...");
// 缺少修改total的代码
}
解决方案:确保循环条件有被改变的可能
越界访问
for(int i=0; i<=menu.length; i++) { // 应该用<
System.out.println(menu[i]);
}
解决方案:注意数组索引从0开始,最大为length-1
混淆循环类型
int count = 5;
do {
System.out.println(count);
count--;
} while(count > 5); // 至少执行一次可能不符合预期
解决方案:根据是否需要至少执行一次来选择循环类型
综合练习题
理论练习
-
下面代码输出什么?
int i = 0; do { System.out.print(i + " "); i += 2; } while(i < 5);
答案:输出"0 2 4 ",因为先执行后判断
-
如何用循环实现输入10个数字并找出最大值? 示例:
Scanner sc = new Scanner(System.in); int max = Integer.MIN_VALUE; for(int i=0; i<10; i++) { System.out.print("输入数字:"); int num = sc.nextInt(); if(num > max) max = num; } System.out.println("最大值:" + max);
-
下面代码有什么问题?
int x = 1; while(x < 10) System.out.println(x); x++; // 缺少大括号
答案:缺少大括号导致x++不在循环体内,造成死循环
实战编程题
-
编写成绩分析程序:
- 输入不确定数量的成绩(以-1结束)
- 统计平均分、最高分、最低分
- 使用合适的循环结构
# 源文件保存为“GradeAnalyzer.java” import java.util.Scanner; public class GradeAnalyzer { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int count = 0, sum = 0; int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE; System.out.println("请输入成绩(-1结束):"); while(true) { System.out.print("成绩" + (count+1) + ": "); int score = sc.nextInt(); if(score == -1) break; sum += score; count++; if(score > max) max = score; if(score < min) min = score; } if(count > 0) { System.out.println("平均分:" + (double)sum/count); System.out.println("最高分:" + max); System.out.println("最低分:" + min); } else { System.out.println("未输入有效成绩"); } sc.close(); } }
运行结果 依次输入成绩,最后一个输入*-1*。
请输入成绩(-1结束): 成绩1: 96 成绩2: 86 成绩3: 98 成绩4: 36 成绩5: -1 平均分:79.0 最高分:98 最低分:36
-
模拟ATM机操作:
- 初始余额1000元
- 支持存款、取款、查询
- 用do-while实现至少执行一次
- 用while处理不确定次数的操作
# 源文件保存为“ATMSystem.java” import java.util.Scanner; public class ATMSystem { public static void main(String[] args) { Scanner sc = new Scanner(System.in); double balance = 1000; int choice; do { System.out.println("\n1.查询 2.存款 3.取款 4.退出"); System.out.print("请选择:"); choice = sc.nextInt(); switch(choice) { case 1: System.out.printf("当前余额:%.2f元\n", balance); break; case 2: System.out.print("存款金额:"); balance += sc.nextDouble(); break; case 3: System.out.print("取款金额:"); double amount = sc.nextDouble(); if(amount > balance) { System.out.println("余额不足!"); } else { balance -= amount; } break; case 4: System.out.println("感谢使用!"); break; default: System.out.println("无效选择!"); } } while(choice != 4); sc.close(); } }
运行结果 依次输入成绩,最后一个成绩输入**-1**。
请输入成绩(-1结束): 成绩1: 98 成绩2: 89 成绩3: 76 成绩4: -1 平均分:87.66666666666667 最高分:98 最低分:76
-
打印特殊数字金字塔:
1 121 12321 1234321
要求:使用嵌套循环实现
# 源文件保存为“NumberPyramid.java” public class NumberPyramid { public static void main(String[] args) { int rows = 4; for(int i=1; i<=rows; i++) { // 打印空格 for(int j=1; j<=rows-i; j++) { System.out.print(" "); } // 打印左半边 for(int k=1; k<=i; k++) { System.out.print(k); } // 打印右半边 for(int l=i-1; l>=1; l--) { System.out.print(l); } System.out.println(); } } }
循环结构就像程序世界的交通规则,不同类型的循环适用于不同的场景。for循环适合已知次数的任务,while处理条件不确定的情况,do-while则保证至少执行一次。掌握它们的综合应用,就能像熟练的交通指挥员一样,让程序流程井然有序地运行。记住,选择循环类型时要像选择交通方式一样,根据具体需求做出最合适的选择。