目录
本章专注案例训练
目的1 : 通过案例复习前面的知识点,加强对知识的理解,巩固所学内容。
01 变量数组
02 运算符 : + - * / % ++ -- && || ! == != > < >= <=
03 程序流程控制 : if 、for 、while 、switch 、死循环
04 跳转关键字 : break 、continue 、return
05 方法
目的2 : 积攒代码量,以训练并提升编程能力、编程思维。
一、案例训练
案例1: 买飞机票。
需求:用户购买机票时,机票原价会按照淡季、旺季,头等舱还是经济舱的情况进行相应的优惠,优惠方案如下:
5-10月:头等舱九折,经济舱8.5折;11月到来年4月为淡季2,头等舱7折,经济舱6.5折,请
11月到来年4月为淡季,头等舱七折,经济舱六点五折。开发程序计算出当前机票的优惠价
分析:根据需求,需要根据月份和舱位类型,进行相应的折扣计算。
1.使用方法进行:
需要输入数据:月份、舱位类型
根据输入的数据进行判断,输出相应的优惠价格
注意:判断字符串是否相等不可以用 == 运算符,应该用 equals() 方法,
但是在这里,我们可以用switch语句进行匹配。
package com.zhl.Test;
import java.util.Scanner;
public class TestDemo1 {
public static void main(String[] args) {
//目的:买飞机票
//需要输入数据:月份、舱位类型
// 根据输入的数据进行判断,输出相应的优惠价格
Scanner sc = new Scanner(System.in);
System.out.println("请输入月份:");
int month = sc.nextInt();
System.out.println("请输入舱位类型:");
String seatType = sc.next();
System.out.println("请输入票价:");
double price = sc.nextDouble();
sc.close();
price = BuyTicket(month, price ,seatType);
System.out.println("票价为:" + price);
}
public static double BuyTicket(int month, double price,String seatType){
if (month >= 5 && month <= 10)
{
//旺季
switch(seatType) {
case "头等舱":
System.out.println("九折优惠!");
price *= 0.9;
break;
case "经济舱":
System.out.println("八五折优惠!");
price *= 0.85;
break;
}
}else{
//淡季
switch(seatType) {
case "头等舱":
System.out.println("七折优惠!");
price *= 0.7;
break;
case "经济舱":
System.out.println("六点五折优惠!");
price *= 0.65;
break;
}
}
return price;
}
}
案例2:开发验证码
需求:开发一个程序,可以生成指定位数的验证码,每位可以是数字、大小写字母。
分析:
1.使用方法进行:
需要输入数据:验证码位数
2.生成验证码,并返回数据
3.方法内部的业务:使用for循环依次生成每位随机字符,并使用一个String类的变量把每个字符连接起来,最后返回该变量即可。
随机验证码的核心实现逻辑是如何进行的?
定义一个for循环,决定生成验证码的位数
生成随机数0 1 2 数据,依次代表当前要随机生成的字符是 :数字 大写字母 小写字母
把 0 1 2 交给switch 生成对应类型的随机字符
在循环外定义一个 String 类型的变量用来连接生成的随机验证码
循环结束后,返回String类型的变量是生成的随机验证码
且最后用一个String类型的变量用来接收方法产生返回的字符,然后打印出来。
package com.zhl.Test;
import java.util.Random;
import java.util.Scanner;
public class TestDemo2 {
public static void main(String[] args) {
//目标:生成随机验证码
/*
需求:开发一个程序,可以生成指定位数的验证码,每位可以是数字、大小写字母。
分析:
1.使用方法进行:
需要输入数据:验证码位数
2.生成验证码,并返回数据
3.方法内部的业务:使用for循环依次生成每位随机字符,并使用一个String类的变量把每个字符连接起来,最后返回该变量即可。
*/
System.out.println("请输入你需要生成的验证码位数:");
Scanner sc = new Scanner(System.in);
int length = sc.nextInt();
//调用方法,生成验证码,并接收返回值
String code = generateRandomCode(length);
//打印验证码
System.out.println("验证码为:" + code);
}
public static String generateRandomCode(int length) {
//1.定义一个for循环,控制产生验证码的位数
Random r = new Random();
//2.定义一个String变量,用于保存生成的验证码
String code = "";
//思路:先随机生成0\1\2,用于决定生成数字/大写字母/小写字母
for (int i = 0; i < length; i++)
{
int type = r.nextInt(3);// 生成0\1\2
//用switch语句来判断类型,并随机生成对应字符
switch (type) {
case 0:
//生成数字
int num = r.nextInt(10); //生成0-9之间的随机数
code += num; //因为 code 是 String 类型,所以可以直接 += 数字 进行字符串拼接
break;
case 1:
//生成大写字母,由于random只能生成随机数,所以利用ASCII码进行转换,即char类型 强制类型转换
// A = 65, Z = 90 = 65 + 26
int char1 = r.nextInt(26) + 65; //即生成65-90之间的随机数
char c1 = (char) char1; //强制类型转换为char类型
code += c1;
break;
case 2:
//生成小写字母,同上 97-122
char char2 = (char)(r.nextInt(26) + 97); //将两步 合成一步
code += char2;
break;
}
}
//3.返回生成的验证码
return code;
}
}
案例3:评委打分
在唱歌比赛中,可能有多名评委要给选手打分,分数是[0,100]之间的整数。
选手最终得分为:去掉一个最高分,去掉一个最低分,剩余分数的平均分。
请编写程序,能够录入多名评委的分数,并计算得出选手的最终分数
分析:
需要用方法,然后要接收评委的人数,然后进行接收分数。
方法还需要返回选手最后的得分。
方法内部:定义数组录入评委的打分,然后遍历数组,去掉最大值和最小值,计算平均分。
这里可以直接计算总分,再去掉最高分、最低分,然后计算平均分,然后返回。
package com.zhl.Test;
import java.util.Scanner;
public class TestDemo3 {
public static void main(String[] args) {
double score = 0;
score = CaculateScore2(6);
System.out.println("选手的得分为:"+ score);
}
public static double CaculateScore2(int n){
//建立一个动态数组,用来录入评委的打分
int[] Score2 = new int[n];
//建立for循环进行录入分数
Scanner sc = new Scanner(System.in);
System.out.println("一共有"+n+"位评委!");
for(int i = 0; i<n;i++){
System.out.println("请输入第"+(i+1)+"位评委打分:");
Score2[i] = sc.nextInt();
}
int Sum2 = 0;
int Max2 = 0;
int Min2 = 0;
//用一个for循环完成
for (int i = 0; i< Score2.length; i++)
{
Sum2 += Score2[i];
if(Max2 <= Score2[i])
{
Max2 = Score2[i];}
if(Min2 >= Score2[i]);
{
Min2 = Score2[i];
}
}
//计算选手最终得分
return 1.0 * (Sum2-Max2-Min2) / (n-2);
}
//下面是自己写的,没有把求最大值、最小值、总分一起算,分开了用了三次循环,较为冗余。
public static double CaculateScore(int n){
//建立一个动态数组,用来录入评委的打分
int[] Score = new int[n];
//建立for循环进行录入分数
Scanner sc = new Scanner(System.in);
for(int i = 0; i<n;i++){
System.out.println("一共有"+n+"位评委!");
System.out.println("请输入第"+(i+1)+"位评委打分:");
Score[i] = sc.nextInt();
}
//进行求和 定义一个Sum进行保存
int Sum = 0;
for (int i = 0; i <n;i++)
{
Sum += Score[i];
}
//求最大值 最小值
int Max = Score[0];
int Min = Score[0];
//求最大值
for (int i = 0; i < n ; i++){
if(Max <= Score[i])
Max = Score[i];
}
//求最小值
for (int i = 0; i <n ; i++){
if(Min >= Score[0])
Min = Score[i];
}
//有效总分
Sum = Sum - Max - Min;
double FinalScore = 0;
//计算最终得分
FinalScore = Sum / (n-2);
return FinalScore;
}
}
案例4:数字加密
某系统的数字密码是一个四位数,如1983,为了安全,需要加密后再传输,加密规则是
对密码中的每位数,都加5再对10求余,最后将所有的数字顺序反转,得到一串加密后的新数,、
请设计出满足本需求的加密程序!
eg: 1 9 8 3
+5 6 14 13 8
%10 6 4 3 8
反转 8 3 4 6
加密后的结果就是 8346
package com.zhl.Test;
public class TestDemo4 {
public static void main(String[] args) {
//目的:案例4:数字加密
/*
某系统的数字密码是一个四位数,如1983,为了安全,需要加密后再传输,加密规则是
对密码中的每位数,都加5再对10求余,最后将所有的数字顺序反转,得到一串加密后的新数,、
请设计出满足本需求的加密程序!
eg: 1 9 8 3
+5 6 14 13 8
%10 6 4 3 8
反转 8 3 4 6
加密后的结果就是 8346
*/
int number = 1983;
String result = encrypt(number);
System.out.println("加密后的结果是:"+result);
}
public static String encrypt(int num) {
//number = 1983;
//1.把数字拆分成一个一个数字,才可以对其进行加密
int[] nums = split(num); //创建一个方法,将数字拆分成一个一个数字
//nums = [1, 9, 8, 3]
//2.遍历这个数组中的每个数组,对其进行加密。
for(int i = 0; i < nums.length; i++){
nums[i] = (nums[i] + 5) % 10;
}
//3.将加密后的数组进行反转 创建一个独立的方法进行反转数组
int[] newNums = reverse(nums);
//newNums = [8, 3, 4, 6]
//4.将加密后的数组转换成字符串
String result = "";
for(int i = 0; i < newNums.length; i++){
result += newNums[i];
}
//result = "8346"
//5.返回加密后的结果
return result;
}
//反转数组
private static int[] reverse(int[] nums) {
for(int i = 0,j = nums.length - 1; i < j; i++,j--){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
return nums;
}
//将数字拆分成一个一个数字
public static int[] split(int num) {
//1.把数字转换成字符串
int[] numbers = new int[4];
numbers[0] = num / 1000;
numbers[1] = (num % 1000) / 100;
numbers[2] = (num % 100) / 10;
numbers[3] = num % 10;
//numbers = [1, 9, 8, 3]
return numbers;
}
}
案例5:数组拷贝
请把一个整型数组,例如存储了数据 11,22,33,拷贝成一个一模一样的新数组出来。
注:
arr1 = {11,22,33};
arr2 = arr1;
为什么不用直接 = 赋值呢?
这里只是拷贝了地址,并没有拷贝内容,所以修改arr2的内容也会影响arr1的内容。
package com.zhl.Test;
public class TestDemo5 {
public static void main(String[] args) {
//目标 案例5:数组拷贝
// 请把一个整型数组,例如存储了数据 11,22,33,拷贝成一个一模一样的新数组出来。
//步骤 1.定义一个整型数组arr,存储数据11,22,33
int[] arr = {11,22,33};
//2.调用copyArray()方法,传入arr数组作为参数,得到一个一模一样的新数组newArr
int[] newArr = copyArray(arr);
//3.打印newArr数组
printArray(newArr);
}
public static int[] copyArray(int[] arr){
//创建新数组
int[] newArr = new int[arr.length];
//数组拷贝
for(int i=0;i<arr.length;i++){
newArr[i] = arr[i];
}
//返回新数组
return newArr;
}
public static void printArray(int[] arr){
//打印数组
System.out.print("[");
for(int i=0;i<arr.length;i++){
if (i!=arr.length-1) {
System.out.print(arr[i]+",");}
else{
System.out.println(arr[i]+"]");
}
}
}
}
案例6:抽奖
一个大V直播时发起了抢红包活动,分别有: 9、666、188、520、99999五个红包。请模拟粉丝来抽奖
按照先来先得,随机抽取,抽完为止,注意一个红包只能被抽一次,先抽或后抽到哪个红包是随机的,示例如下:
请按任意键完成抽奖:aaa
恭喜您,您中奖了:188
请按任意键完成抽奖:ass
恭喜您,您中奖了:666
请按任意键完成抽奖:sasa
恭喜您,您中奖了:99999
请按任意键完成抽奖:dfssfs
恭喜您,您中奖了:9
请按任意键完成抽奖:fsfsf
恭喜您,您中奖了:520
活动结束。。。。。
package com.zhl.Test;
import java.util.Random;
import java.util.Scanner;
public class TestDemo6 {
public static void main(String[] args) {
//目的:一个大V直播时发起了抢红包活动,分别有: 9、666、188、520、99999五个红包。请模拟粉丝来抽奖
// 按照先来先得,随机抽取,抽完为止,注意一个红包只能被抽一次,先抽或后抽到哪个红包是随机的,示例如下:
// 请按任意键完成抽奖:aaa
// 恭喜您,您中奖了:188
// 请按任意键完成抽奖:ass
// 恭喜您,您中奖了:666
// 请按任意键完成抽奖:sasa
// 恭喜您,您中奖了:99999
// 请按任意键完成抽奖:dfssfs
// 恭喜您,您中奖了:9
// 请按任意键完成抽奖:fsfsf
// 恭喜您,您中奖了:520
// 活动结束。。。。。
int[] arr = {9, 666, 188, 520, 99999};
randomP(arr);
}
public static void randomP(int[] arr){
Scanner scanner = new Scanner(System.in);
Random random = new Random();
for (int i = 0; i < 5; i++) {
System.out.println("请按任意键完成抽奖:");
scanner.nextLine();
int index = random.nextInt(arr.length);
//可能会陷入循环等待
while (true){
int index1 = random.nextInt(arr.length);
int money = arr[index1];
if(arr[index] != 0){
System.out.println("恭喜您,您中奖了:" + arr[index]);
arr[index] = 0;
break;
}
}
}
System.out.println("活动结束。。。。。");
}
}
案例7:找素数
判断101到200之间有多少个素数,并输出。
素数的定义:一个大于1的自然数,除了1和它本身外,不能被其他自然数整除。
分析:
定义一个方法,接收一个整数参数,判断该整数是否为素数,如果是素数,则返回true,否则返回false。
然后定义一个变量count,用来记录素数的个数。
然后使用for循环,从101到200,判断每个数是否为素数,如果是素数,则count加1。
循环判断素数只需要判断2到该数的一半即可。
package com.zhl.Test;
public class TestDemo7 {
public static void main(String[] args) {
//判断101到200之间有多少个素数,并输出
Countsu(101, 200);
}
public static void Countsu(int a, int b){
int count = 0;
for(int i =a; i<=b; i++){
if(IsSu(i))
{
count++;
System.out.println("该数是素数:"+i);
}
}
System.out.println("101到200之间有"+count+"个素数");
}
public static boolean IsSu(int num){
for(int i=2; i<(num/2); i++){
if(num%i == 0){
return false;
}
}
return true;
}
}
#方法二
package com.zhl.Test;
public class TestDemo7_2 {
public static void main(String[] args) {
//判断101到200之间有多少个素数,并输出
int count = 0;
OUT: //为外部循环进行标记
for (int i = 101; i <= 200; i++) {
for (int j = 2; j <= i / 2; j++) {
if (i % j == 0) {
//如果i是素数,则跳过此次循环,继续进行下一个i
continue OUT;
}
}
System.out.println(i);
//如果i是素数,则count加1
count++;
}
System.out.println("101到200之间有" + count + "个素数");
}
}
案例8:打印 九九乘法表
使用 \t 使输出的表格左对齐。
package com.zhl.Test;
public class TestDemo8 {
public static void main(String[] args) {
//打印 九九乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
//采用 \t 制表符来控制输出格式
System.out.print(i + "x" + j + "=" + i * j + "\t");
}
System.out.println();//换行
}
}
}
案例9:打印 三角形
打印如下图所示的三角形:
*
***
*****
*******
分析:
注意换行和打印星星数和空格数。
package com.zhl.Test;
public class TestDemo9 {
public static void main(String[] args) {
//打印三角形
// 打印如下图所示的三角形:
// *
// ***
// *****
// *******
int n = 10; // 打印 n 行
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= (n-i); j++) {
// 打印空格
System.out.print(" ");}
// 打印星号
for (int j = 1; j <= (2 * i - 1); j++) {
System.out.print(j % 2 == 0? " ": "*");
}
System.out.println();
}
}
}
案例10:模拟双色球
双色球业务介绍:
投注号码由6个红球和1个蓝球组成。红球号码为1-33,蓝球号码为1-16。
双色球中奖和奖金表:
中奖条件
等奖 红球 篮球 中奖说明 单注奖金分配
一等奖 六个都中 中 6+1 最高1000万
二等奖 六个都中 没中 6+0 最高500万
三等奖 五个红球中 中 5+1 3000
四等奖 五个红球中 没中 5+0 200
四等奖 四个红球中 中 4+1 200
五等奖 四个红球中 没中 4+0 10
package com.zhl.Test;
import java.util.Random;
import java.util.Scanner;
public class TestDemo10 {
public static void main(String[] args) {
//目的:开发一组双色球号码,其中红球号码在1-33,蓝球号码在1-16
//用户 投注的号码
int[] userselect = UseSelectNumbers();
print(userselect);
//系统随机的数组
int[] setcode = SettingCode();
print(setcode);
Judge(userselect,setcode);
}
//设计一个打印数组功能
public static void print(int[] arr){
System.out.print("[");
for(int i = 0;i < arr.length;i++){
System.out.print(i == arr.length-1? arr[i] : arr[i]+",");
}
System.out.print("]");
System.out.println();
}
/*
1.设计一个方法,用于用户投注一组号码并返回 (前六个是红球号码,最后一个是篮球号码)
*/
public static int[] UseSelectNumbers() {
//2.创建数组,用于存储用户投注的七个号码(前六个是红球,最后一个是蓝球)
int[] numbers = new int[7];
Scanner sc = new Scanner(System.in);
//3.遍历数组,先存入红球
for (int i = 0; i < numbers.length-1 ;i++)
{
while (true) {
System.out.println("请您输入第"+(i+1)+"个红球号码(1~33之间,且不能重复):");
//判断用户输入是否正确
int number = sc.nextInt();
if(number< 1 || number > 33)
{
System.out.println("输入错误,你的号码不在1~33之间,请确认!");
}else {
//判断号码是否重复
boolean flag = isSameNumber(numbers,number);
if(flag)
{
System.out.println("您输入的号码重复,请确认!");
}else {
//存入输入的正确号码
numbers[i] = number;
break;
}
}
}
}
while (true) {
System.out.println("请投注最后一个,蓝球号码(1~16):");
int number = sc.nextInt();
if (number < 1 || number > 16) {
System.out.println("你输入的号码不在1~16之间,请确认!");
}else{
numbers[6] = number;
break;
}
}
//返回用户投注的号码
return numbers;
}
//判断号码是否重复
public static boolean isSameNumber(int[] arr,int num){
boolean flag = false;
for (int i = 0; i < arr.length; i++) {
//为了节省性能,在遍历时看看等不等于 0 ,因为号码是根据索引 ,依次往后填入的
if (arr[i]==0)
{
//等于 0 则,不用再往后遍历比较。因为号码没有0
break;
}
if(arr[i] == num)
{
flag = true;
break;
}
}
return flag;
}
/*
设计一个方法,用于系统开奖并返回 (前六个是红球号码,最后一个是篮球号码)
*/
public static int[] SettingCode(){
int[] setcode = new int[7];
Random r = new Random();
//随机红球号码 1~33之间
for (int i = 0; i < setcode.length-1;i++){
while (true) {
//先随机一个号码 因为是指定的随机号码,所以无须判断是否 不符合范围
int randomnum = r.nextInt(33)+1;//因为random随机的是0 到 n-1 所以要 +1,使范围到 1~33
//判断是否重复,若不重复则存入,重复则继续随机
if(!isSameNumber(setcode,randomnum))
{
//不重复,则录入随机号码,跳出循环
setcode[i] = randomnum;
break;
}
}
}
//随机蓝球号码,1~16 ,然后存入数组
int num = r.nextInt(16)+1;
setcode[6] = num;
return setcode;
}
/*
设计一个方法,判断中奖等级
*/
public static void Judge(int[] arr1,int[] arr2){
//计算中奖个数
//红球中奖情况
int Redcount = 0;
for(int i = 0;i < arr1.length-1;i++)
{
for(int j = 0;j < arr2.length-1;j++)
{
if(arr1[i] == arr2[j])
{
Redcount++;
break;
}
}
}
//记录蓝球中奖
int bluecount = arr1[6] == arr2[6] ? 1 : 0 ;
//中奖情况
System.out.println("您命中的红球数是:"+Redcount);
System.out.println("您命中的蓝球数是:"+bluecount);
//计算中奖详情
if(Redcount==6 && bluecount==1)
{
//一等奖
System.out.println("恭喜你,中奖1000万!");
}else if(Redcount==6 && bluecount == 0){
//二等奖
System.out.println("恭喜你,中奖500万!");
} else if (Redcount==5 && bluecount ==1){
//三等奖
System.out.println("恭喜你,中奖3000元!");
} else if (Redcount==5 && bluecount == 0) {
//四等奖
System.out.println("恭喜你,中奖200元!");
}else if(Redcount+bluecount==4){
//五等奖
System.out.println("恭喜你,中奖10元!");
}else if(Redcount < 3 && bluecount == 1){
//六等奖
System.out.println("恭喜你,中奖5元!");
}else {
System.out.println("未中奖!感谢您对福利事业的贡献!!!");
}
}
}