OOP第二次博客作业

jujujujuluo / 2023-05-03 / 原文

OOP第一次博客作业

目录
  • OOP第一次博客作业
    • 前言
      • 第四次作业
      • 第五次作业
      • 第六次作业
    • 设计与分析
        • 7-1 菜单计价程序-3
        • 7-5 日期问题面向对象设计(聚合一)
          • 题目类图
          • 题目源码
          • 题目难点
        • 7-5 日期问题面向对象设计(聚合二)
          • 题目类图
          • 题目源码
          • 题目难点
        • 7-5 ATM机类结构设计(一)
          • 题目类图
          • 题目源码
          • 题目难点
        • 7.4 ATM机类结构设计(二)
          • 题目类图
          • 题目源码
          • 题目难点
    • 踩坑心得
        • 训练集04中7-2不能利用容器判重,利用容器会导致空间复杂度过高,会有几个点MLE,直接数组模拟即可。
        • 结论
    • 改进建议
    • 总结

前言

第四次作业

本次作业总体难度较低,只有第一题的难度较大,另外的题目运用到了一些容器,如HashMap , HashSet等。第一题的题意感觉有些难理解,应该是我自己的问题。班上也没有同学得满分。

第五次作业

本次作业难度较低,大部分同学都得了满分,没得满分的同学也只是错了1,2个测试点。主要知识点是正则表达式的应用,以及之前日期类设计的修改。

第六次作业

本次作业难度较高,前两题简单考察了一下继承和多态。后面三道题的难度相比之前的作业难度有巨大提升,花了好久时间也没能通过所有测试点。

设计与分析

在这里主要对题目集4的7-1 , 题目集5的7-5 ,7 - 6 ,题目集6的7-4 ,7-5进行分析

7-1 菜单计价程序-3

因本题没做出来,所以就不分析了。

7-5 日期问题面向对象设计(聚合一)

题目类图

类图.jpg

题目源码
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int op = sc.nextInt();//输入字符
        int year = sc.nextInt();//年
        int month = sc.nextInt();//月
        int day = sc.nextInt();//日
        DateUtil date = new DateUtil(year , month , day);

        if(op == 1){
            //求下n天
            int n = sc.nextInt();
            if(!date.checkInputValidity() || n < 0){
                System.out.println("Wrong Format");
                System.exit(0);
            }else{
                System.out.println(date.getNextNDays(n).showDate());
            }
        }else if(op == 2){
            //求前n天
            int n = sc.nextInt();
            if(!date.checkInputValidity() || n < 0){
                System.out.println("Wrong Format");
                System.exit(0);
            }else{
                System.out.println(date.getPreviousNDays(n).showDate());
            }

        }else if(op == 3){
            //求相差天数
            int year2 = sc.nextInt();
            int month2 = sc.nextInt();
            int day2 = sc.nextInt();
            DateUtil date2 = new DateUtil(year2 , month2 , day2);
            if(!date.checkInputValidity() || !date2.checkInputValidity()){
                System.out.println("Wrong Format");
                System.exit(0);
               
            }else{
                System.out.println(date.getDaysofDates(date2));
            }


        }else{
            System.out.println("Wrong Format");
        }


    }
}

class DateUtil{
    private Day day;
    //无参构造
    public DateUtil() {
    }
    //有参构造
    public DateUtil(int d, int m, int y) {
        this.day = new Day(d , m , y);
    }

    public Day getDay() {
        return day;
    }

    public void setDay(Day day) {
        this.day = day;
    }
    //检查数据合法性
    public boolean checkInputValidity(){
        return day.getMonth().validate() && day.validate() && day.getMonth().getYear().validate();
    }

    //比较两日期大小
    public boolean compareDates(DateUtil date){
        if(day.getMonth().getYear().getValue() > date.day.getMonth().getYear().getValue()){
            return true;
        }else if(day.getMonth().getYear().getValue() == date.day.getMonth().getYear().getValue() && day.getMonth().getValue() > date.day.getMonth().getValue()){
            return true;
        }else if(day.getMonth().getYear().getValue() == date.day.getMonth().getYear().getValue() && day.getMonth().getValue() == date.day.getMonth().getValue() && this.day.getValue() > date.day.getValue()){
            return true;
        }
        return false;
    }

    //判断两日期是否相等
    public boolean equalTwoDates(DateUtil date){
        return day.getMonth().getYear().getValue() == date.day.getMonth().getYear().getValue() && day.getMonth().getValue() == date.day.getMonth().getValue() && day.getValue() == date.day.getValue();
    }

    //日期格式化
    public String showDate(){
        return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
    }

    //求下n天
    public DateUtil getNextNDays(int n){
        for (int i = 0; i < n; i++) {
            if(day.getMonth().getYear().isLeapYear())
                day.mon_maxnum[2] = 29;
            else
                day.mon_maxnum[2] = 28;
            day.dayIncrement();
            if(day.getValue() == day.mon_maxnum[day.getMonth().getValue()] + 1){
                day.resetMin();
                day.getMonth().monthIncrement();
            }
            if(day.getMonth().getValue() == 13){
                day.getMonth().getYear().yearIncrement();
                day.getMonth().resetMin();
            }
        }
        return new DateUtil(day.getMonth().getYear().getValue() , day.getMonth().getValue(),day.getValue());
    }

    //求前n天
    public DateUtil getPreviousNDays(int n){

        for (int i = 0; i < n; i++) {
            if(day.getMonth().getYear().isLeapYear())
                day.mon_maxnum[2] = 29;
            else
                day.mon_maxnum[2] = 28;
            day.dayReduction();
            if(day.getValue() == 0){
                day.getMonth().monthReduction();
                if(day.getMonth().getValue() == 0){
                    day.getMonth().getYear().yearReduction();
                    day.getMonth().setValue(12);
                }
                day.resetMax();
            }

        }

        return new DateUtil(day.getMonth().getYear().getValue() , day.getMonth().getValue(),day.getValue());
    }

    //求两日期间的天数
    public int getDaysofDates(DateUtil date){
        int res = 0;
        if(this.compareDates(date)){
            while(true){
                if(date.day.getMonth().getYear().isLeapYear())
                    date.day.mon_maxnum[2] = 29;
                else
                    date.day.mon_maxnum[2] = 28;
                date.day.dayIncrement();
                if(date.day.getValue() == date.day.mon_maxnum[date.day.getMonth().getValue()] + 1){
                    date.day.getMonth().monthIncrement();
                    date.day.resetMin();
                }
                if(date.day.getMonth().getValue() == 13){
                    date.day.getMonth().getYear().yearIncrement();
                    date.day.getMonth().resetMin();
                }
                if(date.day.getMonth().getYear().getValue() == day.getMonth().getYear().getValue() && date.day.getMonth().getValue() == day.getMonth().getValue() && date.day.getValue() == day.getValue()){
                    break;
                }
                res++;
            }

        }else{
            while(true){
                if(day.getMonth().getYear().isLeapYear())
                    day.mon_maxnum[2] = 29;
                else
                    day.mon_maxnum[2] = 28;
                day.dayIncrement();
                if(day.getValue() == day.mon_maxnum[day.getMonth().getValue()] + 1){
                    day.getMonth().monthIncrement();
                    day.resetMin();
                }
                if(day.getMonth().getValue() == 13){
                    day.getMonth().getYear().yearIncrement();
                    day.getMonth().resetMin();
                }
                if(date.day.getMonth().getYear().getValue() == day.getMonth().getYear().getValue() && date.day.getMonth().getValue() == day.getMonth().getValue() && date.day.getValue() == day.getValue()){
                    break;
                }
                res++;
            }

        }
        return res + 1;
    }

}

class Day{
    private int value;
    private Month month;
    int[] mon_maxnum = {0 , 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    public Day(){

    }
    public Day(int yearValue, int monthValue, int dayValue) {
        this.value = dayValue;
        this.month = new Month(yearValue , monthValue);
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public Month getMonth() {
        return month;
    }

    public void setMonth(Month month) {
        this.month = month;
    }

    public void resetMin(){
        value = 1;
    }

    public void resetMax(){
        value = mon_maxnum[month.getValue()];
    }
    //判断数据合法性
    public boolean validate(){
        //闰年特判
        if(this.getMonth().getYear().isLeapYear())
            mon_maxnum[2] = 29;

        return value >= 1 && value <= mon_maxnum[this.getMonth().getValue()];
    }

    public void dayIncrement(){
        value ++;
    }

    public void dayReduction(){
        value --;
    }

}

class Month{
    private int value;
    private Year year;
    //无参构造
    public Month(){

    }
    //含参构造
    public Month(int yearValue, int monthValue) {
        this.value = monthValue;
        this.year = new Year(yearValue);
    }

    public void setValue(int value) {
        this.value = value;
    }

    public void setYear(Year year) {
        this.year = year;
    }

    public int getValue() {
        return value;
    }

    public Year getYear() {
        return year;
    }

    public void resetMin(){
        value = 1;
    }
    public void resetMax(){
        value = 12;
    }
    public boolean validate(){
        return value <= 12 && value >= 1;
    }
    public void monthIncrement(){
        value++;
    }
    public void monthReduction(){
        value--;
    }

}

class Year{
    private int value;

    public Year(){

    }
    public Year(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    //判断闰年
    public boolean isLeapYear(){
        return (value % 400 == 0) || (value % 4 == 0 && value % 100 != 0);
    }
    //校验数据合法性
    public boolean validate(){
        return value <= 2050 && value >= 1900;
    }
    //年份加一
    public void yearIncrement(){
        value ++;
    }
    //年份减一
    public void yearReduction(){
        value --;
    }

}
题目难点

本题也没有什么比较难的点,只需要按照题面中给出的类图进行编码就行,注意一些小细节,如月与月,年与年之间的交接,闰年二月的特判。

7-5 日期问题面向对象设计(聚合二)

题目类图

类图.jpg

题目源码
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int op = sc.nextInt();//输入字符
        int year = sc.nextInt();//年
        int month = sc.nextInt();//月
        int day = sc.nextInt();//日
        DateUtil date = new DateUtil(year , month , day);

        if(op == 1){
            //求下n天
            int n = sc.nextInt();
            if(!date.checkInputValidity()){
                System.out.println("Wrong Format");
                return;
            }else{
                System.out.print(year + "-" + month + "-" + day + " " + "next " + n + " " + "days is:");
                System.out.println(date.getNextNDays(n).showDate());
            }

        }else if(op == 2){
            int n = sc.nextInt();
            if(!date.checkInputValidity()){
                System.out.println("Wrong Format");
                return;
            }else{
                System.out.print(year + "-" + month + "-" + day + " " + "previous " + n + " " + "days is:");
                System.out.println(date.getPreviousNDays(n).showDate());
            }
        }else if(op == 3){
            //求相差天数
            int year2 = sc.nextInt();
            int month2 = sc.nextInt();
            int day2 = sc.nextInt();
            DateUtil date2 = new DateUtil(year2 , month2 , day2);
            if(!date.checkInputValidity() || !date2.checkInputValidity()){
                System.out.println("Wrong Format");
                System.exit(0);

            }else{
                System.out.print("The days between " + year + "-" + month + "-" + day + " " + "and" + " " + year2 + "-" + month2 + "-" + day2 + " are:");
                System.out.println(date.getDaysofDates(date2));
            }


        }else{
            System.out.println("Wrong Format");
        }


    }
}

class DateUtil{
    private Day day;
    private Year year;
    private  Month month;
    int[] mon_maxnum = {0 , 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    public DateUtil(){

    }
    public DateUtil(int year, int month, int day) {
        this.day = new Day(day);
        this.year = new Year(year);
        this.month = new Month(month);
    }

    public Day getDay() {
        return day;
    }

    public Year getYear() {
        return year;
    }

    public Month getMonth() {
        return month;
    }

    public void setDay(Day day) {
        this.day = day;
    }

    public void setYear(Year year) {
        this.year = year;
    }

    public void setMonth(Month month) {
        this.month = month;
    }
    public void setDayMin(){
        day.setValue(1);
    }

    public void setDayMax(){
        if(year.isLeapYear()){
            mon_maxnum[2] = 29;
        }else{
            mon_maxnum[2] = 28;
        }
        day.setValue(mon_maxnum[month.getValue()]);
    }

    public boolean checkInputValidity(){
        return year.getValue() <= 2020 && year.getValue() >= 1820 && month.getValue() <= 12 && month.getValue() >= 1 && day.getValue() >= 1 && day.getValue() <= mon_maxnum[month.getValue()];
    }

    //比较两日期大小
    public boolean compareDates(DateUtil date){
        if(year.getValue() > date.year.getValue()){
            return true;
        }else if(year.getValue() == date.year.getValue() && month.getValue() > date.month.getValue()){
            return true;
        }else if(year.getValue() == date.year.getValue() && month.getValue() == date.month.getValue() && day.getValue() > date.day.getValue()){
            return true;
        }
        return false;
    }

    //判断两日期是否相等
    public boolean equalTwoDates(DateUtil date){
        return year.getValue() == date.year.getValue() && month.getValue() == date.month.getValue() && day.getValue() == date.day.getValue();
    }

    //日期格式化
    public String showDate(){
        return year.getValue() + "-" + month.getValue() + "-" + day.getValue();
    }

    //求下n天
    public DateUtil getNextNDays(int n){
        for (int i = 0; i < n; i++) {
            if(year.isLeapYear())
                mon_maxnum[2] = 29;
            else
                mon_maxnum[2] = 28;
            day.dayIncrement();
            if(day.getValue() == mon_maxnum[month.getValue()] + 1){
                day.setValue(1);
                month.monthIncrement();
            }
            if(month.getValue() == 13){
                year.yearIncrement();
                month.setValue(1);
            }
        }
        return new DateUtil(year.getValue(), month.getValue(), day.getValue());
    }

    public DateUtil getPreviousNDays(int n){

        for (int i = 0; i < n; i++) {
            if(year.isLeapYear())
                mon_maxnum[2] = 29;
            else
                mon_maxnum[2] = 28;
            day.dayReduction();
            if(day.getValue() == 0){
                month.monthReduction();
                if(month.getValue() == 0){
                    year.yearReduction();
                    month.setValue(12);
                }
                day.setValue(mon_maxnum[month.getValue()]);
            }

        }

        return new DateUtil(year.getValue(), month.getValue(), day.getValue());
    }

    public int getDaysofDates(DateUtil date){
        int res = 0;
        if(this.compareDates(date)){
            while(true){
                if(date.year.isLeapYear())
                    date.mon_maxnum[2] = 29;
                else
                    date.mon_maxnum[2] = 28;
                date.day.dayIncrement();
                if(date.day.getValue() == date.mon_maxnum[date.month.getValue()] + 1){
                    date.month.monthIncrement();
                    date.day.setValue(1);
                }
                if(date.month.getValue() == 13){
                    date.year.yearIncrement();
                    date.month.resetMin();
                }
                if(date.year.getValue() == year.getValue() && date.month.getValue() == month.getValue() && date.day.getValue() == day.getValue()){
                    break;
                }
                res++;
            }

        }else{
            while(true){
                if(year.isLeapYear())
                    mon_maxnum[2] = 29;
                else
                    mon_maxnum[2] = 28;
                day.dayIncrement();
                if(day.getValue() == mon_maxnum[month.getValue()] + 1){
                    month.monthIncrement();
                    day.setValue(1);
                }
                if(month.getValue() == 13){
                    year.yearIncrement();
                    month.resetMin();
                }
                if(date.year.getValue() == year.getValue() && date.month.getValue() == month.getValue() && date.day.getValue() == day.getValue()){
                    break;
                }
                res++;
            }


        }
        return res + 1;
    }
}

class Day{
    private int value;

    public Day(){

    }
    public Day(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public void dayIncrement(){
        value ++;
    }

    public void dayReduction(){
        value --;
    }

}

class Month{
    private int value;
    //无参构造
    public Month(){

    }
    //含参构造
    public Month(int value) {
        this.value = value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void resetMin(){
        value = 1;
    }
    public void resetMax(){
        value = 12;
    }
    public boolean validate(){
        return value <= 12 && value >= 1;
    }
    public void monthIncrement(){
        value++;
    }
    public void monthReduction(){
        value--;
    }

}

class Year{
    private int value;

    public Year(){

    }
    public Year(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    //判断闰年
    public boolean isLeapYear(){
        return (value % 400 == 0) || (value % 4 == 0 && value % 100 != 0);
    }
    //校验数据合法性
    public boolean validate(){
        return value <= 2050 && value >= 1900;
    }
    //年份加一
    public void yearIncrement(){
        value ++;
    }
    //年份减一
    public void yearReduction(){
        value --;
    }

}
题目难点

本题与上一题的区别就是类与类之间调用的关系不同,money , year , day类都是DateUtil的属性,实现了聚合。难点其实与上一题差不多,就是需要学生对类与类之间的关系有深刻的理解。

7-5 ATM机类结构设计(一)

题目类图

image-20230425163633829

题目源码

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //对账户和ATM机进行初始化
        //ATM机
        ArrayList<String> ATMList1 = new ArrayList<>();
        ATMList1.add("01");
        ATMList1.add("02");
        ATMList1.add("03");
        ATMList1.add("04");
        Bank jsyh = new Bank("中国建设银行", ATMList1);
        ArrayList<String> ATMList2 = new ArrayList<>();
        ATMList2.add("05");
        ATMList2.add("06");
        Bank gsyh = new Bank("中国工商银行", ATMList2);
        //银行
        ArrayList<Bank> bankList = new ArrayList<>();
        bankList.add(jsyh);
        bankList.add(gsyh);
        //用户账户
        ArrayList<String> cardList1 = new ArrayList<>();
        cardList1.add("6217000010041315709");
        cardList1.add("6217000010041315715");
        Account account1 = new Account("杨过", "3217000010041315709", "88888888", 10000.00, bankList, jsyh, cardList1);

        ArrayList<String> cardList2 = new ArrayList<>();
        cardList2.add("6217000010041315718");
        Account account2 = new Account("杨过", "3217000010041315715", "88888888", 10000.00, bankList, jsyh, cardList2);

        ArrayList<String> cardList3 = new ArrayList<>();
        cardList3.add("6217000010051320007");
        Account account3 = new Account("郭靖", "3217000010051320007", "88888888", 10000.00, bankList, jsyh, cardList3);

        ArrayList<String> cardList4 = new ArrayList<>();
        cardList4.add("6222081502001312389");
        Account account4 = new Account("张无忌", "3222081502001312389", "88888888", 10000.00, bankList, gsyh, cardList4);

        ArrayList<String> cardList5 = new ArrayList<>();
        cardList5.add("6222081502001312390");
        Account account5 = new Account("张无忌", "3222081502001312390", "88888888", 10000.00, bankList, gsyh, cardList5);

        ArrayList<String> cardList6 = new ArrayList<>();
        cardList6.add("6222081502001312399");
        cardList6.add("6222081502001312400");
        Account account6 = new Account("张无忌", "3222081502001312399", "88888888", 10000.00, bankList, gsyh, cardList6);

        ArrayList<String> cardList7 = new ArrayList<>();
        cardList7.add("6222081502051320785");
        Account account7 = new Account("韦小宝", "3222081502051320785", "88888888", 10000.00, bankList, gsyh, cardList7);

        ArrayList<String> cardList8 = new ArrayList<>();
        cardList8.add("6222081502051320786");
        Account account8 = new Account("韦小宝", "3222081502051320786", "88888888", 10000.00, bankList, gsyh, cardList8);
        //用户总数组
        ArrayList<Account> accountList = new ArrayList<>();
        accountList.add(account1);
        accountList.add(account2);
        accountList.add(account3);
        accountList.add(account4);
        accountList.add(account5);
        accountList.add(account6);
        accountList.add(account7);
        accountList.add(account8);

        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();

        while (!s.equals("#")) {
            String[] str = s.split("\\s+");
            if (str.length == 1) {
                String card = str[0];
                boolean flag = false;
                int tmp = 0;
                for (int i = 0; i < accountList.size(); i++) {
                    for (int j = 0; j < accountList.get(i).getcardList().size(); j++) {
                        if (card.equals(accountList.get(i).getcardList().get(j))) {
                            flag = true;
                            System.out.printf("¥%.2f\n", accountList.get(i).getBalance());
                            break;
                        }
                    }
                    if (flag)
                        break;
                }
                if (flag == false) {
                    System.out.println("Sorry,this card does not exist.");
                }
            } else {
                Check check = new Check(accountList, str[0], str[1], str[2], Double.parseDouble(str[3]));
                if (check.checkDate()) {
                    Change change = new Change(accountList, str[0], str[1], str[2], Double.parseDouble(str[3]));
                    change.changeMoney();
                    Show show = new Show(accountList, str[0], str[1], str[2], Double.parseDouble(str[3]));
                    show.showInfo();
                }
            }
            s = sc.nextLine();
        }
    }
    }


class Bank {
    String bankName;
    ArrayList<String> atmList;

    public Bank() {

    }

    public Bank(String bankName, ArrayList<String> atmList) {
        this.bankName = bankName;
        this.atmList = atmList;
    }

    public String getBankName() {
        return bankName;
    }

    public void setBankName(String bankName) {
        this.bankName = bankName;
    }

    public ArrayList<String> getAtmList() {
        return atmList;
    }

    public void setAtmList(ArrayList<String> atmList) {
        this.atmList = atmList;
    }
}

class Account {
    private String name;
    private String account;
    private String password;
    private double balance;
    Bank bank;
    ArrayList<Bank> bankList;
    private ArrayList<String> cardList;

    public Account() {

    }

    public Account(String name, String account, String password, double balance, ArrayList<Bank> bankList, Bank bank, ArrayList<String> cardList) {
        this.name = name;
        this.account = account;
        this.password = password;
        this.balance = balance;
        this.bank = bank;
        this.bankList = bankList;
        this.cardList = cardList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Bank getBank() {
        return bank;
    }

    public void setBank(Bank bank) {
        this.bank = bank;
    }

    public ArrayList<Bank> getBankList() {
        return bankList;
    }

    public void setBankList(ArrayList<Bank> bankList) {
        this.bankList = bankList;
    }

    public ArrayList<String> getcardList() {
        return cardList;
    }

    public void setCardList(ArrayList<String> cardList) {
        this.cardList = cardList;
    }
}

//存取后改变余额
class Change {
    ArrayList<Account> accountList;
    String card;
    String password;
    String number;
    double money;

    public Change(ArrayList<Account> accountList, String card, String password, String number, double money) {
        this.accountList = accountList;
        this.card = card;
        this.password = password;
        this.number = number;
        this.money = money;
    }

    public void changeMoney() {
        int t = 0;
        for (int i = 0; i < accountList.size(); i++) {
            for (int j = 0; j < accountList.get(i).getcardList().size(); j++) {
                if (card.equals(accountList.get(i).getcardList().get(j))) {
                    t = i;
                    break;
                }
            }
        }
        accountList.get(t).setBalance(accountList.get(t).getBalance() - money);
    }
}

class Check {
    ArrayList<Account> accountList;
    String card;
    String password;
    String number;
    double money;

    public Check(ArrayList<Account> accountList, String card, String password, String number, double money) {
        this.accountList = accountList;
        this.card = card;
        this.password = password;
        this.number = number;
        this.money = money;
    }

    public boolean checkDate() {
        int flag = 0;
        int i, j;
        int k = 0;
        //检查账号是否正确
        for (i = 0; i < accountList.size(); i++) {
            for (j = 0; j < accountList.get(i).getcardList().size(); j++)
                if (card.equals(accountList.get(i).getcardList().get(j))) {
                    flag = 1;
                    k = i;
                    break;
                }
            if (flag == 1) {
                break;
            }
        }
        //检查密码是否正确
        if (flag == 1) {
            if (password.equals(accountList.get(k).getPassword())) {
                flag = 2;
            } else {
                System.out.println("Sorry,your password is wrong.");//银行卡密码错误
                return false;
            }
        } else {
            System.out.println("Sorry,this card does not exist.");//卡号不存在
            return false;
        }
        //检查ATM机编号是否正确
        if (flag == 2) {
            for (i = 0; i < accountList.get(k).bankList.size(); i++) {
                for (j = 0; j < accountList.get(k).bankList.get(i).atmList.size(); j++) {
                    if (number.equals(accountList.get(k).bankList.get(i).atmList.get(j))) {
                        flag = 3;
                        break;
                    }
                }
            }
        }
        //检查金额是否正确
        if (flag == 3) {
            if (money <= accountList.get(k).getBalance()) {
                flag = 4;
            } else {
                System.out.println("Sorry,your account balance is insufficient.");//取款金额大于账户余额
                return false;
            }
        } else {
            System.out.println("Sorry,the ATM's id is wrong.");//ATM机编号不存在
            return false;

        }
        //检查是否跨行
        if (flag == 4) {
            for (i = 0; i < accountList.get(k).bank.atmList.size(); i++) {
                if (number.equals(accountList.get(k).bank.atmList.get(i))) {
                    flag = 5;
                    break;
                }
            }
        }
        if (flag != 5) {
            System.out.println("Sorry,cross-bank withdrawal is not supported.");//跨行存取款
            return false;
        } else
            return true;
    }
}

class Show {
    ArrayList<Account> accountList;
    String card;
    String password;
    String number;
    double money;

    public Show(ArrayList<Account> accountList, String card, String password, String number, double money) {
        this.password = password;
        this.number = number;
        this.card = card;
        this.accountList = accountList;
        this.money = money;
    }

    public void showInfo() {
        int i, j;
        int t = 0;
        //卡号校验
        for (i = 0; i < accountList.size(); i++) {
            for (j = 0; j < accountList.get(i).getcardList().size(); j++) {
                if (card.equals(accountList.get(i).getcardList().get(j))) {
                    t = i;
                    break;
                }
            }
        }

        if (money >= 0) {//取款
            System.out.printf(accountList.get(t).getName() + "在" + accountList.get(t).bank.bankName + "的" + number + "号ATM机上取款¥%.2f\n", money);
        } else {
            money = -money;
            System.out.printf(accountList.get(t).getName() + "在" + accountList.get(t).bank.bankName + "的" + number + "号ATM机上存款¥%.2f\n", money);
        }
        System.out.printf("当前余额为¥%.2f\n", accountList.get(t).getBalance());
    }
}


题目难点

本题总体难度非常大,考察了很多知识。与之前题目不同的是,本题要求多组输入,这意味着需要利用容器来存储数据,这里我用的是Arraylist,实际上用HashSet应该也是可以的。本题最难的点应该是如何去设计,这里的设计代指要创建多少个类,以及类与类之间的关系。其中最恶心就是错误处理的判断,如果逻辑不清晰的话,肯定会有所遗漏。

7.4 ATM机类结构设计(二)

题目类图

image-20230425163922264

题目源码


import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //对账户和ATM机进行初始化
        //ATM机
        ArrayList<String> ATMList1 = new ArrayList<>();
        ATMList1.add("01");
        ATMList1.add("02");
        ATMList1.add("03");
        ATMList1.add("04");
        Bank jsyh = new Bank("中国建设银行", ATMList1);
        ArrayList<String> ATMList2 = new ArrayList<>();
        ATMList2.add("05");
        ATMList2.add("06");
        Bank gsyh = new Bank("中国工商银行", ATMList2);
        ArrayList<String> ATMList3 = new ArrayList<>();
        ATMList3.add("07");
        ATMList3.add("08");
        ATMList3.add("09");
        ATMList3.add("10");
        ATMList3.add("11");
        Bank nyyh = new Bank("中国农业银行", ATMList3);
        //银行
        ArrayList<Bank> bankList = new ArrayList<>();
        bankList.add(jsyh);
        bankList.add(gsyh);
        bankList.add(nyyh);
        //用户账户
        ArrayList<String> cardList1 = new ArrayList<>();
        cardList1.add("6217000010041315709");
        cardList1.add("6217000010041315715");
        Account account1 = new Account("杨过", "3217000010041315709", "88888888", 10000.00, bankList, jsyh, cardList1);

        ArrayList<String> cardList2 = new ArrayList<>();
        cardList2.add("6217000010041315718");
        Account account2 = new Account("杨过", "3217000010041315715", "88888888", 10000.00, bankList, jsyh, cardList2);

        ArrayList<String> cardList3 = new ArrayList<>();
        cardList3.add("6217000010051320007");
        Account account3 = new Account("郭靖", "3217000010051320007", "88888888", 10000.00, bankList, jsyh, cardList3);

        ArrayList<String> cardList4 = new ArrayList<>();
        cardList4.add("6222081502001312389");
        Account account4 = new Account("张无忌", "3222081502001312389", "88888888", 10000.00, bankList, gsyh, cardList4);

        ArrayList<String> cardList5 = new ArrayList<>();
        cardList5.add("6222081502001312390");
        Account account5 = new Account("张无忌", "3222081502001312390", "88888888", 10000.00, bankList, gsyh, cardList5);

        ArrayList<String> cardList6 = new ArrayList<>();
        cardList6.add("6222081502001312399");
        cardList6.add("6222081502001312400");
        Account account6 = new Account("张无忌", "3222081502001312399", "88888888", 10000.00, bankList, gsyh, cardList6);

        ArrayList<String> cardList7 = new ArrayList<>();
        cardList7.add("6222081502051320785");
        Account account7 = new Account("韦小宝", "3222081502051320785", "88888888", 10000.00, bankList, gsyh, cardList7);

        ArrayList<String> cardList8 = new ArrayList<>();
        cardList8.add("6222081502051320786");
        Account account8 = new Account("韦小宝", "3222081502051320786", "88888888", 10000.00, bankList, gsyh, cardList8);

        ArrayList<String> cardList9 = new ArrayList<>();
        cardList9.add("6640000010045442002");
        cardList9.add("6640000010045442003");
        Account account9 = new Account("张三丰", "3640000010045442002", "88888888", 10000.00, bankList, jsyh, cardList9);

        ArrayList<String> cardList10 = new ArrayList<>();
        cardList10.add("6640000010045441009");
        Account account10 = new Account("令狐冲", "3640000010045441009", "88888888", 10000.00, bankList, gsyh, cardList10);

        ArrayList<String> cardList11 = new ArrayList<>();
        cardList11.add("6630000010033431001");
        Account account11 = new Account("乔峰", "3630000010033431001", "88888888", 10000.00, bankList, nyyh, cardList11);

        ArrayList<String> cardList12 = new ArrayList<>();
        cardList12.add("6630000010033431008");
        Account account12 = new Account("洪七公", "3630000010033431008", "88888888", 10000.00, bankList, nyyh, cardList12);
        //用户总数组
        ArrayList<Account> accountList = new ArrayList<>();
        accountList.add(account1);
        accountList.add(account2);
        accountList.add(account3);
        accountList.add(account4);
        accountList.add(account5);
        accountList.add(account6);
        accountList.add(account7);
        accountList.add(account8);
        accountList.add(account9);
        accountList.add(account10);
        accountList.add(account11);
        accountList.add(account12);



        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();

        while (!s.equals("#")) {
            String[] str = s.split("\\s+");
            if (str.length == 1) {
                String card = str[0];
                boolean flag = false;
                int tmp = 0;
                for (int i = 0; i < accountList.size(); i++) {
                    for (int j = 0; j < accountList.get(i).getcardList().size(); j++) {
                        if (card.equals(accountList.get(i).getcardList().get(j))) {
                            flag = true;
                            System.out.printf("业务:查询余额 ¥%.2f\n", accountList.get(i).getBalance());
                            break;
                        }
                    }
                    if (flag)
                        break;
                }
                if (flag == false) {
                    System.out.println("Sorry,this card does not exist.");
                }
            } else {
                Check check = new Check(accountList, str[0], str[1], str[2], Double.parseDouble(str[3]));
                if (check.checkDate()) {
                    Change change = new Change(accountList, str[0], str[1], str[2], Double.parseDouble(str[3]));
                    change.changeMoney();
                    Show show = new Show(accountList, str[0], str[1], str[2], Double.parseDouble(str[3]));
                    show.showInfo();
                }
            }
            s = sc.nextLine();
        }
    }
}


class Bank {
    String bankName;
    ArrayList<String> atmList;

    public Bank() {

    }

    public Bank(String bankName, ArrayList<String> atmList) {
        this.bankName = bankName;
        this.atmList = atmList;
    }

    public String getBankName() {
        return bankName;
    }

    public void setBankName(String bankName) {
        this.bankName = bankName;
    }

    public ArrayList<String> getAtmList() {
        return atmList;
    }

    public void setAtmList(ArrayList<String> atmList) {
        this.atmList = atmList;
    }
}

class Account {
    private String name;
    private String account;
    private String password;
    private double balance;
    Bank bank;
    ArrayList<Bank> bankList;
    private ArrayList<String> cardList;

    public Account() {

    }

    public Account(String name, String account, String password, double balance, ArrayList<Bank> bankList, Bank bank, ArrayList<String> cardList) {
        this.name = name;
        this.account = account;
        this.password = password;
        this.balance = balance;
        this.bank = bank;
        this.bankList = bankList;
        this.cardList = cardList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Bank getBank() {
        return bank;
    }

    public void setBank(Bank bank) {
        this.bank = bank;
    }

    public ArrayList<Bank> getBankList() {
        return bankList;
    }

    public void setBankList(ArrayList<Bank> bankList) {
        this.bankList = bankList;
    }

    public ArrayList<String> getcardList() {
        return cardList;
    }

    public void setCardList(ArrayList<String> cardList) {
        this.cardList = cardList;
    }
}

//存取后改变余额
class Change {
    ArrayList<Account> accountList;
    String card;
    String password;
    String number;
    Bank bank;
    double money;

    public Change(ArrayList<Account> accountList, String card, String password, String number, double money) {
        this.accountList = accountList;
        this.card = card;
        this.password = password;
        this.number = number;
        this.money = money;
    }

    public void changeMoney() {
        int k = 0;
        for (int i = 0; i < accountList.size(); i++) {
            for (int j = 0; j < accountList.get(i).getcardList().size(); j++)
                if (card.equals(accountList.get(i).getcardList().get(j))) {
                    k = i;
                    break;
                }
        }
        int flag = 0;
        for (int i = 0; i < accountList.get(k).bank.atmList.size(); i++) {
            if (number.equals(accountList.get(k).bank.atmList.get(i))) {
                flag = 1;
                break;
            }
        }
        double p1 = 0;
        double p2 = 0;
        if (number.equals("07") || number.equals("08") || number.equals("09") || number.equals("10") || number.equals("11")) {
            p1 = 0.04;
        }

        if (number.equals("05") || number.equals("06")) {
            p1 = 0.03;
        }
        if (number.equals("01") || number.equals("02") || number.equals("03") || number.equals("04")){
            p1 = 0.02;
        }

        if (card.equals("6640000010045442002") || card.equals("6640000010045442003") || card.equals("6640000010045441009") || card.equals("6630000010033431001") || card.equals("6630000010033431008")) {
            if (flag == 1) {
                if (accountList.get(k).getBalance() >= 0) {
                    double num = accountList.get(k).getBalance() - money;
                    if (num >= 0) {
                        accountList.get(k).setBalance(num);
                    } else {
                        accountList.get(k).setBalance(num + num * 0.05);
                    }
                } else {
                    accountList.get(k).setBalance(accountList.get(k).getBalance() - money * 1.05);
                }
            } else {
                if (accountList.get(k).getBalance() >= 0) {
                    double num = accountList.get(k).getBalance() - money;
                    if (num >= 0) {
                        accountList.get(k).setBalance(num - money * p1);
                    } else {
                        accountList.get(k).setBalance(num + num * 0.05 - money * p1);
                    }
                } else {
                    accountList.get(k).setBalance(accountList.get(k).getBalance() - money * 1.05);
                }
            }
        } else {
            if (flag == 1)
                accountList.get(k).setBalance(accountList.get(k).getBalance() - money);
            else
                accountList.get(k).setBalance(accountList.get(k).getBalance() - money * (p1 + 1));
        }
    }
}

class Check {
    ArrayList<Account> accountList;
    String card;
    String password;
    String number;
    double money;

    public Check(ArrayList<Account> accountList, String card, String password, String number, double money) {
        this.accountList = accountList;
        this.card = card;
        this.password = password;
        this.number = number;
        this.money = money;
    }

    public boolean checkDate() {
        int flag = 0;
        int i, j;
        int k = 0;
        //检查账号是否正确
        for (i = 0; i < accountList.size(); i++) {
            for (j = 0; j < accountList.get(i).getcardList().size(); j++)
                if (card.equals(accountList.get(i).getcardList().get(j))) {
                    flag = 1;
                    k = i;
                    break;
                }
            if (flag == 1) {
                break;
            }
        }
        //检查密码是否正确
        if (flag == 1) {
            if (password.equals(accountList.get(k).getPassword())) {
                flag = 2;
            } else {
                System.out.println("Sorry,your password is wrong.");//银行卡密码错误
                return false;
            }
        } else {
            System.out.println("Sorry,this card does not exist.");//卡号不存在
            return false;
        }
        //检查ATM机编号是否正确
        if (flag == 2) {
            for (i = 0; i < accountList.get(k).bankList.size(); i++) {
                for (j = 0; j < accountList.get(k).bankList.get(i).atmList.size(); j++) {
                    if (number.equals(accountList.get(k).bankList.get(i).atmList.get(j))) {
                        flag = 3;
                        break;
                    }
                }
            }
        }
        //检查金额是否正确
        if (flag == 3) {
            if (card.equals("6640000010045442002") || card.equals("6640000010045442003") || card.equals("6640000010045441009") || card.equals("6630000010033431001") || card.equals("6630000010033431008")) {
                if (accountList.get(k).getBalance() >= (1 + 0.05) * money - 50000) {

                } else {
                    System.out.println("Sorry,your account balance is insufficient.");//取款金额大于账户余额
                    return false;
                }
            } else {
                if (money <= accountList.get(k).getBalance()) {
                    flag = 4;
                } else {
                    System.out.println("Sorry,your account balance is insufficient.");//取款金额大于账户余额
                    return false;
                }
            }
        } else {
            System.out.println("Sorry,the ATM's id is wrong.");//ATM机编号不存在
            return false;

        }
        //检查是否跨行
        if (flag == 4) {
            for (i = 0; i < accountList.get(k).bank.atmList.size(); i++) {
                if (number.equals(accountList.get(k).bank.atmList.get(i))) {
                    flag = 5;
                    break;
                }
            }
        }
        if (flag != 5) {
            return true;
        } else
            return true;
    }
}

class Show {
    ArrayList<Account> accountList;
    String card;
    String password;
    String number;
    double money;

    public Show(ArrayList<Account> accountList, String card, String password, String number, double money) {
        this.password = password;
        this.number = number;
        this.card = card;
        this.accountList = accountList;
        this.money = money;
    }

    public void showInfo() {
        int i, j;
        int t = 0;
        //卡号校验
        for (i = 0; i < accountList.size(); i++) {
            for (j = 0; j < accountList.get(i).getcardList().size(); j++) {
                if (card.equals(accountList.get(i).getcardList().get(j))) {
                    t = i;
                    break;
                }
            }
        }

        String bankName;
        if (number.equals("01") || number.equals("02") || number.equals("o3"))
            bankName = "中国建设银行";
        else if (number.equals("04") || number.equals("05") || number.equals("06"))
            bankName = "中国工商银行";
        else
            bankName = "中国农业银行";
        if (money >= 0) {//取款
            System.out.printf("业务:取款 " + accountList.get(t).getName() + "在" + bankName + "的" + number + "号ATM机上取款¥%.2f\n", money);
        }
        System.out.printf("当前余额为¥%.2f\n", accountList.get(t).getBalance());
    }
}


题目难点

相比上一题,本题增加了一种逻辑,支持了跨行贷款,并且需要收取相应的手续费。虽然看似只是一个简单的需求,但实现起来还是有点困难的,主要是因为计算功能需要进行大量的修改,而且还需要进行一些特判。

踩坑心得

训练集04中7-2不能利用容器判重,利用容器会导致空间复杂度过高,会有几个点MLE,直接数组模拟即可。

HashSet代码

import java.util.Scanner;
import java.util.HashSet;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n  = sc.nextInt();
        HashSet st = new HashSet();
        int flag = 0;
        for(int i = 0;i < n;i ++){
            int x = sc.nextInt();
            if(st.add(x)){
                
            }else{
                System.out.print("YES");
                return;
            }
        }
        System.out.print("NO");
       
    }

}

结果

image-20230425171333798

数组模拟代码

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n  = sc.nextInt();
        int [] arr = new int[n + 1];
        for(int i = 0;i < n; i++){
            arr[i] = sc.nextInt();
        }
        
        Arrays.sort(arr);
        for(int i = 0;i < n - 1; i++){
            if(arr[i] == arr[i + 1]){
                System.out.print("YES");
                return ;
            }
        }
        System.out.print("NO");
        
       
    }

}

结果

image-20230425171443284

结论

在写题前先观察一下题目的数据范围,在思考相应的解法。此外,不要太依赖容器,应当知道一些朴素的解法。(set map 大法好

改进建议

  • 对于训练集06的7-5中的Arraylist可以用HashSet还替换

  • 对于训练集05的7-2中的字符排序可以利用Sort() 与 训练集04相似,训练集04中要求按单词长度排序,可以重载sort来达到目的

    image-20230425170824523

总结

  • 通过这三次作业,我的java语法基础有了明显的提高 。对于java的三大特性有了一个基本的理解,但是还不能熟练的运用。
  • 个人的设计思想也有所欠缺,在面对一道实际问题时,经常需要花费较长一段时间才能理清题目里的基本逻辑。尤其是第六次作业中的ATM机类的设计,不能对题目的所有限制考虑清楚,导致测试点没有全部通过。
  • 接下来,将会继续学习java中抽象类和接口的学习,同时花时间巩固一下已经学过的内容,尤其是正则表达式的使用(实在是太难记了)。