06 Java 案例

一、买飞机票

1.需求

用户购买机票时,机票原价会按照淡季、旺季,头等舱还是经济舱的情况进行相应的优惠,优惠方案如下:5-10月为旺季,头等舱9折,经济舱8.5折;11月到来年4月为淡季,头等舱7折,经济舱6.5折,请开发程序计算出用户当前机票的优惠价。

2.分析

  • 方法是否需要接收数据?  需要接收机票原件、当前月份、舱位类型;
  • 方法是否需要返回数据?  需要返回计算出的机票优惠价。
  • 方法内部:先使用if判断月份是旺季还是淡季,然后使用switch分支判断是头等舱还是经济舱。

3.代码

package it;

public class Test1 {
    public static void main(String[] args) {
        // 目标: 完成飞机票的案例。
        double price = calculate(1000, 8, "经济舱");
        System.out.println("优惠价是:" + price);
    }



    public static double calculate(double price, int month, String type) {
        // 1. 判断当前月份是淡季还是旺季
        if (month >= 5 && month <= 10) {
            // 旺季
            // 2. 判断舱位类型
            switch (type) {
                case "头等舱":
                    price *= 0.9; // price = price * 0.9;
                    break;

                case "经济舱":
                    price *= 0.85;
                    break;
            }
        } else {
            // 淡季
            switch (type) {
                case "头等舱":
                    price *= 0.7; // price = price * 0.9;
                    break;

                case "经济舱":
                    price *= 0.65;
                    break;
            }
        }
        return price;

    }

}

二、开发验证码

1.需求

开发一个程序,可以生成指定位数的验证码,单位可以是数字、大小写字母。

2.分析

  • 方法是否需要接收数据?  需要接收一个整数,控制生成验证码的位数
  • 方法是否需要返回数据?  需要生成的验证码
  • 方法内部的业务:使用for循环依次生成每位随机字符,并使用一个String类的变量把每个字符连接起来,最后返回该变量即可

3.代码

package itcom;

import java.util.Random;

public class Test2 {
    public static void main(String[] args) {
        // 目标:完成生成随机验证码
        System.out.println(createCode(5));
    }

    public static String createCode(int n){
        Random r = new Random();
        // 3. 定义一个String类型的变量用于记住产生的每位随机字符
        String code = "";

        // 1. 定义一个for循环用于控制产生
        for (int i = 1; i <= n ; i++) {
            // i = 1 2 3 4 5
            // 2. 为每个位置生成一个随机字符: 可能是数字、大小写字母。
            // 思路:随机一个0 1 2之间的数字出来:0代表随机一个数字字符,1、2代表随机大写字母、小写字母
            int type = r.nextInt(3);
            switch (type){
                case 0:
                    //随机一个数字字符
                    code += r.nextInt(10);  // 0 - 9 code = code + 随机的十个数之一
                    break;
                case 1:
                    //随机一个大写字符 A 65   Z 65+25  ( 0 - 25 ) + 68
                    char ch1 = (char) (r.nextInt(26) + 65);
                    code += ch1;
                    break;
                case 2:
                    //随机一个小写字符 a 97   z 97+25   ( 0 - 25 ) + 97
                    char ch2 = (char) (r.nextInt(26) + 97);
                    code += ch2;
                    break;
            }

        }
        return code;
    }
}

三、评委打分

1.需求

在歌唱比赛中,可能有多名评委要给选手打分,分数是[0 - 100]之间的整数,选手最后得分为:去掉最高分,最低分后剩余分数的平均分,请编写程序能够录入多名评委的分数,并算出选手的最终得分。

2.分析

  • 方法是否需要接收数据进行处理? 需要接收评委的人数
  • 方法是否需要返回数据?需要返回计算出的选手得分
  • 方法内部的业务:定义数组,录入评委的分数存入到数组中去,接着,我们就需要遍历数组中的分数,计算出总分,并找出最高分,最低分,最后按照这些数据算出选手最终得分并返回即可。

3.代码

package itcom;

import java.util.Scanner;

public class Test3 {
    public static void main(String[] args) {
        // 目标:完成评委打分案例
        System.out.println("当前选手得分是:" + getAverageScore(6));
    }

    public static double getAverageScore(int number){
        // 1. 定义一个动态初始化的数组,负责后期存入评委的打分
        int[] scores = new int[number]; // 假设有6个评委
        // scores = [0 ,0 ,0 ,0 ,0 ,0]

        // 2. 遍历数组的每个位置,依次录入评委的分数
        // 需要扫描器接收数据
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < scores.length; i++) {
            // i = 0 1 2 3 4 5
            System.out.println("请您录入第"+ (i + 1) +"个评委的分数:");
            int score = sc.nextInt(); // 等待输入分数
            scores[i] = score;
        }

        // 3. 从数组中计算出总分,找出最高分,最低分
        int sum = 0; // 求总分用的变量
        int max = scores[0]; // 求最大值的
        int min = scores[0]; // 求最小值的

        // 遍历数组找出这些数据的
        for (int i = 0; i < scores.length; i++) {
            // i = 0 1 2 3 4 5
            int score = scores[i];
            // 求和
            sum += score;
            // 求最大值
            if(score > max){
                max = score;
            }
            // 求最小值
            if(score < min){
                min = score;
            }
        }

        // 4. 计算出平均分并返回
        return 1.0 * (sum - min - max) / (number - 2);
        // 保留小数
    }

}

四、数字加密

1.需求

某系统的数字是一个四位数,如1983,为了安全,需要加密后再传播,加密规则是:对密码中的每位数,都加5,再对10求余,最后将所有数字顺序反转,得到一串加密后的新数,请设计出满足本需求的加密程序!

数字1983
+5614138
%106438
反转8346

最后得到的数字是8346

2.分析

  • 方法是否需要接收数据进行处理?需要接收四位数字密码,进行加密处理
  • 方法是否需要返回数据?需要返回加密结果
  • 方法内部的业务:将四位数字密码拆分成一个一个的数字,存入到数组中去,遍历数组中的每个数字,按照题目需求进行加密!最后,再把加密后的数字拼接起来返回即可!

3.代码

package itcom;

public class Test4 {
    public static void main(String[] args) {
        // 目标:完成数字加密的开发
        System.out.println(encrypt(1983));
    }

    public static String encrypt(int number){
        // number 1983
        // 1. 把密码拆分成一个一个的数字,才可以对其进行加密。
        // 两种方式:一种是直接在这里对密码进行拆分,另一种是把拆分密码这个功能交给独立的方法来解决,建议用第二种
        int[] numbers = spilt(number);
        // number = [1 ,9 ,8 ,3]

        // 2. 遍历这个数组中的每个数字,可对其进行加密处理
        for (int i = 0; i < numbers.length; i++) {
            // i = 0 1 2 3
            numbers[i] = (numbers[i] + 5) % 10;
        }
        // numbers = [6 ,4 , 3 ,8]

        // 3. 可以先倒着遍历每个加密的数字再连接起来作为加密后的结果;也可以先反转再顺着去遍历;用第二种方式
        // 先反转,并将反转的操作交给一个独立的方法来完成
        reverse(numbers);
        // numbers = [8 ,3 ,4 ,6]


        // 4. 把这些加密的数字拼接起来作为加密后的结果返回即可。
        String data = "";
        for (int i = 0; i < numbers.length; i++) {
            data += numbers[i];
        }

        return data;
    }

    private static void reverse(int[] numbers) {
        // 反转数组
        // numbers = [6 ,4 , 3 ,8]
        //              i    j
        for (int i = 0, j = numbers.length - 1; i < j; i++,j--) {
            // 交换i和j位置处的值
            // 1. 把后一个位置处的值交给一个临时变量先存起来
            int temp = numbers[j];
            // 2. 把前一个位置处的值赋值给后一个位置
            numbers[j] = numbers[i];
            // 3. 把后一个位置处原来的值(由临时变量记住着) 赋值给每一个位置
            numbers[i] = temp;
        }
    }

    private static int[] spilt(int number) {
        // 拆分密码放入整型数组int[]中
        // number = 1983
        int[] numbers = new int[4];
        numbers[0] = number / 1000;
        numbers[1] = (number / 100) % 10;
        numbers[2] = (number / 10) % 10;
        numbers[3] = number % 10;
        return numbers;
    }


}

五、数组拷贝

1.需求

请把一个整型数组,例如存了数据:11, 22, 33,拷贝成一个一摸一样的新数组出来。

2.分析

  • 方法是否需要接收数据进行处理? 需要接收一个整型数组(原数组)。
  • 方法是否需要返回数据? 需要返回一个新的,一摸一样的整型数组
  • 方法内部的业务:创建一个长度一样的整型数组为新数组,并把原数组的元素对应位置赋值给新数组,最终返回新数组即可

3.代码

package itcom;

public class Test5 {
    public static void main(String[] args) {
        // 目标:掌握数组拷贝
        int[] arr = {11, 22, 33};
        int[] arr2 = copy(arr);
        printArray(arr2);
    }


    public static void printArray(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.println("]");
    }

    public static int[] copy(int[] arr){
        // arr = [11, 22, 33]
        //         0   1   2

        // 1. 创建一个长度一样的整型数组出来
        int[] arr2 = new int[arr.length];
        // arr2 = [0, 0, 0]
        //         0  1  2

        // 2. 把原数组的元素值对应位置赋值给新数组
        for (int i = 0; i < arr.length; i++) {
            // i = 0 1 2
            arr2[i] = arr[i];
        }

        return arr2;
    }
}

六、抢红包

1.需求

一个大V直播时发起了抢红包活动,分别有:9、 666、 188、 520、 99999五个红包。请模拟粉丝来抽奖,按照先来先得,随机抽取,抽完即止,注意:一个红包只能抽一次,先抽或后抽哪一个红包是随机的,示例如下(不一定是下面的顺序):

2.分析

  • 方法是否需要接收数据进行处理?需要接收一个数组,里面是5个名额,表示5个红包
  • 方法是否需要返回数据? 不需要
  • 方法内部完成本需求的第一个方案:写个for循环控制抽奖5次,每次抽奖,都从数组中随机找出一个金额,如果该金额不是0,则代表抽中,接着用0替换该位置处的金额,然后继续下一个粉丝的抽奖;如果抽中的金额发现是0,代表该位置处的红包之前就被别人抽走了,则从新从数组中随机找出一个金额,连接判断!直至抽中的金额不是0!
  • 方法内部完成本需求的第二个方案:先把数组里面的5个金额打乱顺序,打乱后的顺序就认为是中奖顺序;接着,写个for循环,执行5次,每次都提示抽奖;每次抽奖,都依次取出数组中的每个位置处的金额作为中奖金额即可

3.代码

第一种:

package itcom;

import java.util.Random;
import java.util.Scanner;

public class Test6 {
    public static void main(String[] args) {
        // 目标:完成抢红包案例的开发
        int[] moneys = {9, 666, 188, 520, 99999};
        start(moneys);
    }

    public static void start(int[] moneys){
        // money = [9, 666, 188, 520, 99999]
        //          0   1    2    3     4

        Scanner sc = new Scanner(System.in);
        Random r = new Random();
        // 1. 定义一个for循环,控制抽奖5次
        for (int i = 1; i <= 5 ; i++) {
            // 2. 提示粉丝抽奖
            System.out.println("请您输入任意内容进行抽奖:");
            sc.next(); // 等待用户输入内存,按了回车才往下走的。

            // 3. 为当前这个粉丝找一个随机的红包
            while(true) {
                int index = r.nextInt(moneys.length); // 0 - 4
                int money = moneys[index];

                // 4. 判断这个红包是否不为0
                if (money != 0) {
                    System.out.println("恭喜您,您抽中了红包:" + money);
                    moneys[index] = 0;
                    break; // 结束这次抽奖!
                }
            }
        }
        System.out.println("活动结束。。");
    }

}

第二种:(这种性能较好)

package itcom;

import java.util.Random;
import java.util.Scanner;

public class Test6two {
    public static void main(String[] args) {
        // 目标: 打乱奖金的顺序,依次发给粉丝
        int[] arr = {9, 666, 188, 520, 99999};
        int length = arr.length;
        for(int i=0;i<length;i++){
            int iRandNum = (int)(Math.random() * length);
            int temp = arr[iRandNum];
            arr[iRandNum] = arr[i];
            arr[i] = temp;
        }

        //输出
        printArray(arr);

        Scanner sc = new Scanner(System.in);

        for (int i = 0; i < 5; i++) {
            System.out.println("请您输入任意内容进行抽奖:");
            sc.next() ;
            System.out.println("恭喜您,抽中了红包!" + arr[i]);
        }
    }

    public static void printArray(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.println("]");
    }


}

七、找素数

1.需求

判断101-200之间有多少素数?

除了1和它本身以外,不能被其他正整数整除,就叫素数

2.分析

  • 方法是否需要接收数据进行处理? 需要接收101以及200以便找该区间中的素数
  • 方法是否需要返回数据? 需要返回找到的素数个数
  • 方法内部的实现逻辑:使用for循环来产生101到200之间的每个数;每拿到一个数,判断该数是否是素数;判断规则是:从2开始遍历到该数的一半的数据,看是否有数据可以整除它,有则不是素数,没有则是素数;根据判定的结果来决定是否输出这个数据(是素数则输出);最后还需要统计素数的个数并返回

3.代码

第一种:

package itcom;

public class Test7 {
    public static void main(String[] args) {
        // 目标:完成找素数
        System.out.println("当前素数的个数是:" + search(101, 200));
    }

    public static int search(int start,int end){
        int count = 0; // 统计素数的个数
        // start = 101    end = 200
        // 1. 定义一个for循环找到101到200之间的每个数据
        for (int i = start; i <= end ; i++) {
            // i = 101 102 103 ... 200

            // 信号位思想
            boolean flag = true; // 假设的意思,默认认为当前i记住的数据是素数

            // 2. 判断当前i记住的这个数据是否是素数
            for (int j = 2; j <= i/2 ; j++) {
                if(i % j ==0){
                    // i当前记住的这个数据就不是素数
                    flag = false;
                    break;
                }
            }

            // 3. 根据判定的结果决定是否输出i当前记住的数据:是素数才输出显示。
            if(flag){
                System.out.println(i);
                count++;
            }
        }
        return count;
    }


}

第二种:(拓展)

package itcom;

public class Test7_2 {
    public static void main(String[] args) {
        // 目标:完成找素数
        int count = 0; // 统计素数的个数
        // start = 101    end = 200
        // 1. 定义一个for循环找到101到200之间的每个数据

        OUT:
        //新语法:为外部循环指定标签
        for (int i = 101; i <= 200; i++) {
            // i = 101 102 103 ... 200

            // 2. 拦截判断该数是否是素数
            for (int j = 2; j <= i / 2; j++) {
                if (i % j == 0) {
                    // i这个数肯定不是素数,不能打印
                    // 拓展:那就直接结束上一个for i 外部循环的当次执行。怎么执行?
                    continue OUT;
                }
            }

            count++;
            System.out.println(i);

        }
        System.out.println("素数个数是:" + count);
    }
}

第三种:(用方法来实现)

package itcom;

public class Test7_3 {
    public static void main(String[] args) {
        for (int i = 101; i <= 200 ; i++) {
            // i = 101 102 103 ... 200
            // i遍历到的当前数据是否是素数,是则输出,不是则不输出。
            if(check(i)){
                System.out.println(i);
            }
        }
    }

    public static boolean check(int data){
        for (int i = 2; i <= data / 2 ; i++) {
            if(data % i ==0){
                return false;
            }
        }
        return true;
    }
}

八、打印乘法表、打印三角形[拓展案例]

1.需求

九九乘法表、三角形

2.代码

九九乘法表:

package itcom;

public class Test8 {
    public static void main(String[] args) {
        // 1. 定义一个for循环控制打印多少行
        for (int i = 1; i <= 9 ; i++) {
            // i = 1 2 3 ... 9
            // 2. 定义一个内部循环控制每行打印多少列
            for (int j = 1; j < i; j++) {
                // i 行    j 列
                System.out.print(j + "X" + i + "=" + (j * i) + "\t");
            }
            System.out.println(); //换行
        }
    }
}

三角形:

package itcom;

/**
      *
     ***
    *****
   *******
 本质;计算机本质只能打印行,所以按照行思考
 先找规律,再写程序
 行(i)   先打空格(n-i)   再打星星(2i-1)    换行
 1          3             1
 2          2             3
 3          1             5
 4          0             7

 */
public class Test8_2 {
    public static void main(String[] args) {
        // 1. 先定义一个循环控制打印多少行
        int n = 4;
        for (int i = 1; i <= 4 ; i++) {
            // 2. 控制打印多少个空格
            for (int j = 1; j <= (n-i) ; j++) {
                System.out.print(" ");
            }


            // 3. 控制打印多少个星星
            for (int j = 1; j <= (2*i - 1) ; j++) {
                System.out.print("*");
            }
            /**
             控制星星中间有空格
             for (int j = 1; j <= (2*i - 1) ; j++) {
                System.out.print(j % 2 == 0 ? " " : "*");
             }
             */


            // 4. 换行
            System.out.println();
        }
    }
}

九、模拟双色球[拓展案例]

1.需求

2.分析

代码要用到三个方法:

  • 用于让用户投注一号码(前6个是红球,最后1个是蓝球),并返回用户投注的号码
  • 系统随机一组中奖号码(前6个是红球,最后一个是蓝球),并返回这组中奖号码
  • 传入两组号码,用来判断用户投注号码的中奖情况,并输出

1. 用户投注一组号码

注意:6个红球号码的范围是1~33之间,且不能重复;1个蓝球号码的范围在:1~16之间

2.随机一组中奖号码出来

3.判断用户是否中奖

3.代码

package itcom;

import java.util.Random;
import java.util.Scanner;

public class Test9 {
    public static void main(String[] args) {
        // 目标:完成双色球系统的开发。
        int[] userNumber = userSelectNumber();
        System.out.println("您投注的号码:");
        printArray(userNumber);

        int[] luckNumbers = createLuckNumbers();
        System.out.println("中奖的号码:");
        printArray(luckNumbers);

        judge(userNumber,luckNumbers);
    }

    public static void printArray(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.println("]");
    }

    // 1.设计一个方法,用于让用户投注一组号码并返回(前6个是红球号码,最后1个是蓝球号码)。
    public static int[] userSelectNumber(){
        // 2. 创建一个整型数组,用于存储用户投注的7个号码(前6个是红球号码,最后1个是蓝球号码)
        int[] numbers = new int[7];
        // numbers = [0, 0, 0, 0, 0, 0, 0]
        //            0  1  2  3  4  5  6

        Scanner sc = new Scanner(System.in);
        // 3. 遍历前6个位置,让用户依次投注6个红球号码,存入
        for (int i = 0; i < numbers.length - 1; i++) {
            // i = 0 1 2 3 4 5

            while(true){ // 死循环,不是true不能出循环
                // 4. 开始让用户为当前位置投注一个红球号码(1~33之间,不能重复)
                System.out.println("请您输入第" + (i + 1) + "个红球号码(1~33之间。不能重复)");
                int number = sc.nextInt();

                // 5. 先判断用户输入的红球号码是否在1~33之间
                if(number < 1 || number > 33){
                    System.out.println("对不起,您输入的红球号码不在1~33之间,请确认");
                }else{
                    // 号码是在1~33之间了,接着还要继续判断这个号码是否重复,不重复才可用使用
                    if(exist(numbers,number)){
                        // number当前这个红球号码是重复了。
                        System.out.println("对不起,您当前输入的红球号码前面选择过,重复了,请确认!");
                    }else{
                        // number记住的这个号码没有重复了,就可以使用了。
                        numbers[i] = number;
                        break;  // 结束当次投注,结束了当前死循环
                    }

                }
            }
        }

        // 6. 投注最后一个蓝球号码
        while (true) {
            System.out.println("请您输入最后1个蓝球号码(1-16):");
            int number = sc.nextInt();
            numbers[6] = number;
            if(number < 1 || number > 16){
                System.out.println("对不起,您输入的蓝球号码范围不对");
            }else{
                numbers[6] = number;
                break; // 蓝球号码录入成功,结束循环
            }
        }
        return numbers;
    }

    private static boolean exist(int[] numbers, int number) {
        // 需求:判断number这个数字是否在numbers数组中存在
        // numbers = [12, 25, 18, 0, 0, 0]
        // number = 26
        for (int i = 0; i < numbers.length; i++) {
            if(numbers[i] == 0){
                break;  //优化性能。就不用遍历后面的
            }
            if(numbers[i] == number){
                return true;
            }
        }
        return false;
    }


    // 2.设计一个方法:随机一组中奖号码出来(6个红球号码,1个蓝球号码)
    public static int[] createLuckNumbers(){
        // 1. 创建一个整型数组,用于存储这7个号码
        int[] numbers = new int[7];

        Random r = new Random();
        // 2. 遍历前6个位置数,依次随机一个红球号码存入(1-33不重复)
        for (int i = 0; i < numbers.length; i++) {
            // i = 0 1 2 3 4 5

            while(true){
                // 3. 为当前这个位置随机一个红球号码出来存入。 1 - 33 ==> -1 ===> (0 , 32) + 1
                int number = r.nextInt(33) + 1;

                // 4. 判断这个号码是否之前出现过(红球号码不能重复)
                if(!exist(numbers,number)){
                    // number不重复
                    numbers[i] = number;
                    break; // 结束死循环,代表找到了当前这个位置的一个不重复的红球号码了
                }

            }
        }
        // 5. 录入一个蓝球号码。 1-16
        numbers[6] = r.nextInt(16) + 1;
        return numbers;
    }

    // 3. 设计一个方法,用于判断用户的中奖情况
    public static void judge(int[] userNumbers,int[] luckNumbers){
        // userNumbers = [12, 14, 16, 18, 23, 26, 8]
        // luckNumbers = [16, 17, 18, 19, 26, 32, 8]示例

        // 2. 分别定义2个变量用于记住红球命中了几个以及蓝球命中了几个
        int redCount = 0;
        int blueCount = 0;

        // 先判断红球名字的数量
        // 遍历用户投注的号码的前6个红球
        for (int i = 0; i < userNumbers.length - 1; i++) {
            // userNumbers[i]
            // 开始遍历中奖号码的前6个红球号码,看用户当前选择的这个号码是否命中了
            for (int j = 0; j < luckNumbers.length - 1; j++) {
                if(userNumbers[i] == luckNumbers[j]){
                    redCount++;
                    break;
                }
            }
        }

        // 3. 判断蓝球是否命中了
        blueCount = userNumbers[6] == luckNumbers[6] ? 1 : 0;

        System.out.println("您命中的红球数量是:" + redCount);
        System.out.println("您命中的蓝球数量是:" + blueCount);

        // 4. 判断中奖详情,并输出结果
        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 || redCount == 4 && blueCount == 1){
            System.out.println("恭喜您,中奖200元~~");
        }else if(redCount == 4 && blueCount == 0 || redCount == 3 && blueCount == 1){
            System.out.println("恭喜您,中奖10元~~");
        }else if(redCount < 3 && blueCount == 1){
            System.out.println("恭喜您,中奖5元~~");
        }else{
            System.out.println("感谢您对福利事业做出的巨大贡献~~");
        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值