专题课(编程案例)
涉及到的知识点
⚫ 变量、数组
⚫ 运算符:基本运算符、关系运算符、逻辑运算符…
⚫ 程序流程控制:if、switch;for、while;死循环、循环嵌套
⚫ 跳转关键字:break、continue、return。
⚫ 方法
⚫ …
案例一:买飞机票
需求:机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。
按照如下规则计算机票价格:旺季(5-10月)头等舱9折,经济舱8.5折,淡季(11月到来年4月)头等舱7折,经济舱6.5折。
分析:
①定义一个方法可以进行键盘录入机票原价、月份和机舱类型。
②使用if判断月份是是旺季还是淡季,使用switch分支判断是头等舱还是经济舱。
③选择对应的折扣进行计算并返回计算的结果。
示例代码如下:
// 接收用户输入数据:飞机票原价、仓位类别、月份Scannersc=newScanner(System.in); System.out.println("请输入月份(1-12):"); intmonth=sc.nextInt(); System.out.println("请输入舱位类型(头等舱、经济舱):"); StringplaneType=sc.next(); System.out.println("请输入机票价格:"); doubleticketPrice=sc.nextDouble(); // 4.调用方法,统计结果doubleticketMoney=planeTicket(ticketPrice, month, planeType); System.out.println("机票优惠后的价格是:"+ticketMoney); } /*** create by: 全聚德在逃烤鸭、* description: 统计优惠后的飞机票价格* create time: 2022/3/31 0031 10:29** @param ticketPrice* @param month* @param planeType* @return double*/// 2.定义方法接收信息,统计优惠后的价格返回publicstaticdoubleplaneTicket(doubleticketPrice, intmonth, StringplaneType) { // 3.判断用户选择的信息情况if (month>=5&month<=10) { // 旺季switch (planeType) { case"头等舱": ticketPrice*=0.9; // ticketPrice = ticketPrice * 0.9;break; case"经济舱": ticketPrice*=0.85; break; default: System.out.println("输入的舱位类型有误!"); ticketPrice=-1; // 表示当前无法计算价格 } } elseif ((month>=1&month<=12) & (month>=11|month<=4)) { // 淡季switch (planeType) { case"头等舱": ticketPrice*=0.7; // ticketPrice = ticketPrice * 0.9;break; case"经济舱": ticketPrice*=0.65; break; default: System.out.println("输入的舱位类型有误!"); ticketPrice=-1; // 表示当前无法计算价格 } } else { System.out.println("输入月份有误!"); ticketPrice=-1; } returnticketPrice; // 最终价格
案例二:找素数
需求:判断101-200之间有多少个素数,并输出所有素数。
说明:如果除了1和它本身之外,不能被其他正整数整除的数,就叫素数。
分割线
分析:
101-200之间的数据可以采用循环依次拿到;每拿到一个数,判断该数是否是素数。
判断规则是:从2开始遍历到该数的一半的数据,看是否有数据可以整除它,有则不是素数,没有则是素数。
示例代码如下:
publicstaticvoidmain(String[] args) { intstartNumber=101; intfinishNumber=200; System.out.println(startNumber+"至"+finishNumber+"中的素数为"); intnumber=getPrimeNumber(startNumber, finishNumber); System.out.println("共"+number+"个"); } /*** create by: 全聚德在逃烤鸭、* description: 给定边界值,找出并打印位于两个边界值之间的所有素数* create time: 2022/3/31 0031 11:30** @param startNumber* @param FinishNumber* @return int*/publicstaticintgetPrimeNumber(intstartNumber, intFinishNumber) { intnumber=0; // 记录素数个数// 1.定义一个循环,找出startNumber至FinishNumber之间的全部数据for (inti=startNumber; i<=FinishNumber; i++) { // 信号位:标记当前数据是否为素数booleanisPrime=true; // 默认是素数// 3.判断当前遍历的数据是否是素数for (intj=2; j<=i/2; j++) { if (i%j==0) { isPrime=false; break; } } // 3.根据判断结果选择是否打印该数据,若是素数则打印if (isPrime) { System.out.print(i+"\t"); // 打印该素数number++; // 每找到一个素数,素数总数目+1 } } returnnumber; }
案例三:开发验证码
需求:定义方法实现随机产生一个5位的验证码,每位可能是数字、大写字母、小写字母。
分析:
①定义一个方法,生成验证码返回:方法参数是位数、方法的返回值类型是String。
②在方法内部使用for循环生成指定位数的随机字符,并连接起来。
③把连接好的随机字符作为一组验证码进行返回。
示例代码如下:
publicstaticvoidmain(String[] args) { intn=5; // 4.调用获取验证码的方法,得到一个随机的验证码Stringcode=creatCode(n); System.out.println("随机的"+n+"位验证码为:"+code); } /*** create by: 全聚德在逃烤鸭、* description: 随机产生指定位数的验证码并返回* create time: 2022/3/31 0031 15:32** @param n* @return java.lang.String*/// 1.定义方法实现随机产生验证码,每位可能是数字、大写字母、小写字母,并将产生的验证码返回publicstaticStringcreatCode(intn) { // 3.定义一个字符串变量用于记录生成的随机字符Stringcode=""; // 初始值为空Randomr=newRandom(); // 2.定义一个for循环,循环n次,依次生成随机字符for (inti=0; i<n; i++) { // 具体是生成数字、大写字母还是小写字母,是随机的inttype=r.nextInt(3); // 0:生成数字 1:生成大写字母 2:生成小写字母switch (type) { // 数字case0: intnumber=r.nextInt(10); // (0-9)code+=number; // 将数字累加进验证码break; // 大写字母case1: charupperCase= (char) (r.nextInt(26) +65); // 大写字母在ASCⅡ码中对应数字(A:65至Z:90),需要由int型强转为char型code+=upperCase; // 将大写字母累加进验证码break; // 小写字母case2: charlowerCase= (char) (r.nextInt(26) +97); // 大写字母在ASCⅡ码中对应数字(a:97至Z:122),需要由int型强转为char型code+=lowerCase; // 将小写字母累加进验证码break; } } returncode; // 将最终生成的验证码返回 }
案例四:数组元素的复制
需求:把一个数组中的元素复制到另一个新数组中去。
分析:
①需要动态初始化一个数组,长度与原数组一样。
②遍历原数组的每个元素,依次赋值给新数组。
③输出两个数组的内容。
示例代码如下:
publicstaticvoidmain(String[] args) { int[] arr1= {10, 20, 30}; // int[] arr2 = arr1; // 只是把arr1中存储的数组对象的地址赋值给arr2存储,本质上还是同一个数组,不是数组复制int[] arr2=newint[arr1.length]; copyArray(arr1, arr2); // 调用复制数组的方法,完成数组复制// 调用打印数组数组内容的方法,查看两个数组内容是否一致printArray(arr1); printArray(arr2); } /*** create by: 全聚德在逃烤鸭、* description: 把一个数组中的元素复制到另一个数组中去* create time: 2022/3/31 0031 16:04** @param arr1* @param arr2* @return void*/publicstaticvoidcopyArray(int[] arr1, int[] arr2) { // 完成数组复制for (inti=0; i<arr1.length; i++) { arr2[i] =arr1[i]; } } /*** create by: 全聚德在逃烤鸭、* description: 遍历并打印数组中的每一个元素值* create time: 2022/3/31 0031 16:07** @param arr* @return void*/publicstaticvoidprintArray(int[] arr) { System.out.print("["); // 遍历数组中的每一个元素值,并将其打印出来for (inti=0; i<arr.length; i++) { // 查看是否为最后一位索引,若是,则不打印制表符System.out.print(i==arr.length-1?arr[i] : arr[i] +"\t"); } System.out.println("]"); }
注:
int[] arr1 = {10, 20, 30};
int[] arr2 = arr1; // 只是把arr1中存储的数组对象的地址赋值给arr2存储,本质上还是同一个数组,不是数组复制
案例五:评委打分
需求:在唱歌比赛中,有6名评委给选手打分,分数范围是[0-100]之间的整数。选手的最后得分为:去掉最高分、最低分后的4个评委的平均分,请完成上述过程并计算出选手的得分。
分析:
①把6个评委的分数录入到程序中去 --->使用数组
②遍历数组中每个数据,进行累加求和,并找出最高分、最低分。
③按照分数的计算规则算出平均分。
示例代码如下:
publicstaticvoidmain(String[] args) { // 定义一个动态初始化数组,用于后期录入6个评委的分数int[] scores=newint[6]; // 录入评委的分数Scannersc=newScanner(System.in); for (inti=0; i<scores.length; i++) { System.out.println("请输入第"+ (i+1) +"评委的成绩"); // 把分数存入数组的对应索引位置scores[i] =sc.nextInt(); } System.out.println("平均分为"+getAverageScore(scores)); // 调用求平均分的方法并将结果打印出来 } /*** create by: 全聚德在逃烤鸭、* description: 求一组数据中去掉最高分、最低分后的平均分,分数范围是[0-100]之间的整数* create time: 2022/3/31 0031 18:33** @param scores* @return double*/publicstaticdoublegetAverageScore(int[] scores) { // 判断数组内是否有数据,若没有则给出提示,并返回值-1if (scores==null|scores.length==0) { System.out.println("成绩输入有误!"); return-1; // 代表数据有误 } inttotalScore=0; // 定义变量,存储总分数,初始值为0intmax=scores[0]; // 默认第1个索引的元素值为最大值intmin=scores[0]; // 默认第1个索引的元素值为最小值// 遍历数组中的每个元素值,找出最大值和最小值,求出总分for (inti=0; i<scores.length; i++) { // 涉及到求总分问题,所以必须从第0个索引位置开始// 判断每个元素的数据值是否在0-100范围内,若超出范围则给出提示,并返回值-1if (scores[i] <0|scores[i] >100) { System.out.println("成绩输入超出范围0-100!"); return-1; } // 若当前索引位置的元素值大于最大值,则将该元素值设为最大值if (scores[i] >max) { max=scores[i]; } // 若当前索引位置的元素值小于最小值,则将该元素值设为最小值if (scores[i] <min) { min=scores[i]; } totalScore+=scores[i]; // 累加各个元素的数据值 } // 去掉一个最高分,去掉一个最低分,求平均分doubleaverageScore= (totalScore-max-min) *1.0/ (scores.length-2); // 一定要*1.0,使int型自动转换为double型,否则在计算中出现小数时会发生小数丢失returnaverageScore; // 将最终求得的平均分返回 }
注:
求解平均分时一定要在计算前*1.0,使int型自动转换为double型,否则在计算中出现小数时会发生小数丢失。
案例六:数字加密
需求:某系统的数字密码,采用加密方式进行传输,规则如下:先得到每位数,然后每位数都加上5,再对10求余,最后将所有数字反转,得到一串新数。
如1983,加密过程如下图所示。
分析:
①将每位数据存入到数组中去,遍历数组每位数据,按照规则进行更改,把更改后的数据从新存入到数组中。
②将数组的前后元素进行交换,数组中的最终元素就是加密后的结果。
示例代码如下:
publicstaticvoidmain(String[] args) { Scannersc=newScanner(System.in); // 1.定义一个数组存储需要加密的数据System.out.println("请输入需要加密的数字位数:"); intlength=sc.nextInt(); // 手动输入加密数字的位数,可以动态加密不同长度的数字int[] arr=newint[length]; // 2.录入需要加密的数字for (inti=0; i<arr.length; i++) { System.out.println("请输入第"+ (i+1) +"位数字:"); intnumber=sc.nextInt(); arr[i] =number; } // 3.调用打印数组内容的方法,查看原数字System.out.println("加密前"); printArray(arr); // 4.调用对数组中的数据进行加密的方法(核心逻辑)arr=digitalEncryption(arr); // 5.调用打印数组内容的方法,查看加密后的数字System.out.println("加密后"); printArray(arr); } /*** create by: 全聚德在逃烤鸭、* description: 打印数组内容* create time: 2022/4/1 0001 9:25** @param arr* @return void*/publicstaticvoidprintArray(int[] arr) { if (arr==null|arr.length==0) { System.out.println("数组为空!"); } else { System.out.print("数组内容为:["); for (inti=0; i<arr.length; i++) { System.out.print(i==arr.length-1?arr[i] : arr[i] +","); } System.out.println("]"); } } /*** create by: 全聚德在逃烤鸭、* description: 将数组中的数据顺序颠倒* create time: 2022/4/1 0001 10:15** @param arr* @return int[]*/publicstaticint[] digitalEncryption(int[] arr) { if (arr==null|arr.length==0) { System.out.println("数组为空!"); } else { // 执行每位数+5,%10for (inti=0; i<arr.length; i++) { arr[i] = (arr[i] +5) %10; } inttemp=0; // 执行数组内容顺序翻转/* 完成数据顺序翻转的原理:①定义2个变量分别占数组的首尾位置②一个变量往前走,一个变量往后走,同步交换双方位置处的值。*/for (inti=0, j=arr.length-1; i<j; i++, j--) { temp=arr[i]; arr[i] =arr[j]; arr[j] =temp; } } returnarr; }
完成数据顺序翻转的原理:
①定义2个变量分别占数组的首尾位置。
②一个变量往前走,一个变量往后走,同步交换双方位置处的值。
案例七:模拟双色球
需求:从红色球号码中选择6个号码,从蓝色球号码中选择1个号码,组合为一注投注号码,红色球号码从1—33中选择;蓝色球号码从1—16中选择。
中奖条件与奖金表如下图所示。
业务流程分析:
1.随机一组号码并返回,代表双色球中奖号码
2.用户输入一组号码并返回,代表用户选择的双色球号码
3.比对这两组号码,判断用户的中奖情况。
1.随机一组中奖号码分析:
①中奖号码由6个红球和1个蓝球组成(注意:6个红球要求不能重复)。
②定义方法用于返回一组中奖号码(7个数据),返回的形式是一个整型数组。
核心逻辑:如何去保证随机的6个中奖的红球号码不重复的
①每次随机一个红球号码后去数组中判断是否存在。
②存在需要重新随机一个数字直到不重复为止。
2.用户输入一组号码分析:
①定义一个方法,该方法可以录入用户输入的6个红球和1个篮球号码
②该方法最终需要返回一个数组,数组中就是用户录入的号码(7位)。
核心逻辑:如何去保证7个用户选择的号码不重复且符合范围
①每次选择后,判断该数字是否超出范围以及是否重复
②若超出范围或者数据重复,则要求用户重新输入一个数字直到符合范围且不重复为止。
3.中奖情况判断的分析:
①定义一个方法,可以接收中奖号码的数组,用户选号的数组。
②根据命中红球数和篮球数判断最终的中奖情况并输出详情和中奖金额。
核心逻辑:如何去统计红球的命中数量
①遍历用户的每个选号,然后遍历中奖号码的数组。
②看当前选号是否在中奖号码中存在,存在则命中数量加1。
示例代码如下:
publicstaticvoidmain(String[] args) { // 1.调用随机生成中奖号码的方法,返回一个数组变量int[] luckyNumbers=creatLuckyNumber(); // printArray(luckyNumbers);// 2.调用用户选号的方法让用户输入7个号码,返回一个数组变量int[] userInputNumbers=userInputNumbers(); // printArray(userInputNumbers);// 3.调用判断中奖情况的方法,输出中奖情况详情judgeWinning(luckyNumbers, userInputNumbers); } /*** create by: 全聚德在逃烤鸭、* description: 打印数组内容* create time: 2022/4/1 0001 15:48** @param arr* @return void*/publicstaticvoidprintArray(int[] arr) { System.out.print("["); for (inti=0; i<arr.length; i++) { System.out.print(i==arr.length-1?arr[i] : arr[i] +","); } System.out.println("]"); } /*** create by: 全聚德在逃烤鸭、* description:生成随机一组中奖号码 随机6个红球号码(1-33,且不能重复),随机1个蓝球号码(1-16),将数据存储到数组中* create time: 2022/4/1 0001 14:48** @param* @return int[]*/publicstaticint[] creatLuckyNumber() { Randomr=newRandom(); // 定义一个动态初始化数组,存储7个数字int[] numbers=newint[7]; // 遍历数组,为每个位置生成对应号码for (inti=0; i<numbers.length-1; i++) {// 遍历前6个位置,生成不重复的6个随机的红球号码,范围为1-33OUT: // OUT标签,标记循环// 定义死循环,当生成的第i个号码是之前生成过的重复号码时,重新生成while (true) { intrandom=r.nextInt(33) +1; // 随机生成第i个红球号码// 遍历第i个红球号码之前的所有号码,判断是否重复,若重复,则重新生成for (intj=0; j<i; j++) { if (random==numbers[j]) { continueOUT; // 号码重复,跳出当次循环,跳转到被OUT标签标记的while循环处,重新生成随机数,重新判断 } } numbers[i] =random; // 遍历完成i之前所有的数字,没有重复,则将该数据赋值给第i个红球break; // 第i个红球号码赋值完毕,结束当前while循环,进行下一次for循环,为下一个红球号码赋值 } } intlength=numbers.length; numbers[length-1] =r.nextInt(16) +1; // 生成随机的第7个蓝球号码,范围为1-16returnnumbers; // 将得到的随机7个数字的数组返回 } /*** create by: 全聚德在逃烤鸭、* description:用户输入一组号码,6个红球号码(1-33,且不能重复),1个蓝球号码(1-16),将数据存储到数组中* create time: 2022/4/1 0001 15:32** @param* @return int[]*/publicstaticint[] userInputNumbers() { Scannersc=newScanner(System.in); // 定义一个动态初始化数组,存储7个数字int[] numbers=newint[7]; // 要求用户选择6个红球号码,范围1-33for (inti=0; i<numbers.length-1; i++) { // 依次输入6个红球号码,判断6个红球号码是否均满足范围要求且不重复,若是则将号码存储到数组中,否则重新输入while (true) { booleanisDifferent=true; // 默认当前选择的号码是与之前选择的号码是不同的System.out.println("请选择第"+ (i+1) +"个红球号码:"); intnumber=sc.nextInt(); // 判断输入的数据是否在1-33范围内,若不在,则给出提示,并跳出本次循环,重新输入if (number<1|number>33) { System.out.println("选择号码超出范围1-33,请重新选择!"); continue; // 跳出本次while循环,重新当前输入红球选择的数据 } // 遍历之前已经选择完毕的号码,判断是否有重复的,若有,则给出提示并重新选择;若没有,则继续for (intj=0; j<i; j++) { // 判断是否重复if (numbers[j] ==number) { System.out.println("号码"+number+"重复,请重新选择!"); isDifferent=false; // 将是否不同置为falsebreak; // 无需继续判断,跳出当前for循环 } } // 若isDifferent为true,说明遍历完第(i+1)个之前的号码,均没有重复的,本次选择号码有效if (isDifferent) { numbers[i] =number; // 将选择的号码添加到数组中break; // 跳出当前while循环,选择下一个红球号码 } } } // 要求用户录入1个蓝球号码,范围1-16while (true) { System.out.println("请选择蓝球号码:"); intnumber=sc.nextInt(); // 判断输入的数据是否在1-16范围内,若在,则将其添加到数组中,并跳出本次循环,否则给出提示并重新输入if (number>=1&number<=16) { intlength=numbers.length; numbers[length-1] =number; // 将选择的号码添加到数组中break; // 跳出本次循环 } System.out.println("选择号码超出范围1-16,请重新选择!"); } returnnumbers; // 将输入的7个数字的数组返回 } /*** create by: 全聚德在逃烤鸭、* description: 中奖情况判断 接收中奖号码的数组,用户选号的数组,根据命中红球数和篮球数判断最终的中奖情况并输出详情和中奖金额。* create time: 2022/4/1 0001 19:40** @param creatLuckyNumber* @param userInputNumbers* @return void*/publicstaticvoidjudgeWinning(int[] creatLuckyNumber, int[] userInputNumbers) { intredSame=0; // 定义变量存储红球猜中个数// 遍历用户红球的每个选号,然后遍历红球中奖号码的数组,看当前选号是否在中奖号码中存在,存在则红球命中数量加1for (inti=0; i<userInputNumbers.length-1; i++) { // userInputNumbers.length - 1,蓝球不包括在内// 拿出当前选择的号码,遍历所有的中奖号码,并进行比较,查看是否猜中,若猜中则红球命中数量加1for (intj=0; j<creatLuckyNumber.length-1; j++) { // creatLuckyNumber.length - 1,蓝球不包括在内// 如果存在中奖号码,则红球猜中个数+1,跳出当前循环if (userInputNumbers[i] ==creatLuckyNumber[j]) { // 当前选择的号码在中奖号码中存在,即代表当前号码猜中了redSame++; break; } } } // 定义变量存储蓝球是否猜中booleanblueSame=creatLuckyNumber[creatLuckyNumber.length-1] ==userInputNumbers[userInputNumbers.length-1] ?true : false; // 打印最终中奖号码、选择号码以及结果情况System.out.print("您选择的号码是:"); printArray(userInputNumbers); System.out.print("中奖号码是:"); printArray(creatLuckyNumber); System.out.println("您猜中了"+redSame+"个红球,"+ (blueSame?1 : 0) +"个蓝球"); // 根据猜中红球与蓝球的数目打印对应的奖励结果if (blueSame) { switch (redSame) { case6: System.out.println("恭喜您,中了一等奖,中6+1,奖金最高1000W"); break; case5: System.out.println("恭喜您,中了三等奖,中5+1,奖金3000元"); break; case4: System.out.println("恭喜您,中了四等奖,中4+1,奖金200元"); break; case3: System.out.println("恭喜您,中了五等奖,中3+1,奖金10元"); break; case2: System.out.println("恭喜您,中了六等奖,中2+1,奖金5元"); break; case1: System.out.println("恭喜您,中了六等奖,中1+1,奖金5元"); case0: System.out.println("恭喜您,中了六等奖,中0+1,奖金5元"); break; default: System.out.println("数据输入错误!"); } } else { switch (redSame) { case6: System.out.println("恭喜您,中了二等奖,中6+0,奖金最高500W"); break; case5: System.out.println("恭喜您,中了四等奖,中5+0,奖金200元"); break; case4: System.out.println("恭喜您,中了五等奖,中4+0,奖金10元"); break; default: System.out.println("很遗憾您没有中奖!"); } } }