grafspee pta4-6作业总结

本文将对pta上1-3次作业进行总结

nchu_22201129_xiahouyuchen

目录

一,前言

二,设计与分析

三,踩坑心得

四,改进建议

五,总结

 

前言

本次作业较上次作业难度有较大的提升,特别是第六次作业的水利以及atm的构造

第四次作业

知识点:类,循环,判断

题量:7道题

难度:除了第一道其他还行

第五次作业

知识点:类,循环,判断

题量:6道题

难度:中等

第六次作业

知识点:类

题量:5道题

难度:比较难

 

设计与分析

题目集4

7-1菜单计价程序-3

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {

Dish\[\] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

点菜记录类:保存订单上的一道菜品记录

Record {

int orderNum;//序号\\

Dish d;//菜品\\

int portion;//份额(1/2/3代表小/中/大份)\\

int getPrice()//计价,计算本条记录的价格\\

}

订单类:保存用户点的所有菜的信息。

Order {

Record\[\] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

### 输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

### 输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+“:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 12/2/3
1 麻婆豆腐 2 2
2 油淋生菜 1 3
end
 

输出样例:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 38
 

输入样例1:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 17/0/0
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end
 

输出样例1:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1: 22
 

输入样例2:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2023/3/22 16/59/59
1 麻婆豆腐 2 2
2 油淋生菜 1 3
1 delete
end
 

输出样例2:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
table 1 out of opening hours
 

输入样例3:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/5 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
5 delete
7 delete
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
7 delete
end
 

输出样例3:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
delete error;
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
delete error;
table 1 out of opening hours
table 2: 63
 

输入样例4:

在这里给出一组输入。例如:

麻婆豆腐 12
油淋生菜 9
table 1 2022/12/3 19/5/12
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
table 2 2022/12/3 15/03/02
1 麻婆豆腐 2 2
2 油淋生菜 1 3
3 麻辣鸡丝 1 2
1 4 麻婆豆腐 1 1
7 delete
end
 

输出样例4:

在这里给出相应的输出。例如:

table 1: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
table 2: 
1 麻婆豆腐 36
2 油淋生菜 27
麻辣鸡丝 does not exist
4 table 2 pay for table 1 12
delete error;
table 1: 63
table 2: 75

题目分析:

题目中暗示我们需要使用菜单类,订单类以及每一道点的记录类来生成每桌的账单。根据输入条件,我们的工作就是不断产生订单、删除订单记录、代点菜以及最后进行结算,输出各桌的账单记录。

思路

下面分别介绍各个类的设计以及以下步骤的实现:

  • 输入菜单类和订单类的数据
  • 读入每桌的订单,对每桌进行处理
  • 根据时间和营业时间计算出折扣
  • 处理点菜记录,并加入订单类
  • 进行删除操作,修改订单
  • 添加代点菜
  • 计算每桌总价格,总折扣,输出结果

用到的Java知识

是否包含这个字符串:indexOf(String s),若包含则返回下标,若不包含则返回-1。

字符串分解:split(String s1, int n)或split(String s1)

生成一张Hash表,将菜名作为key进行记录,当发现重复的菜品时,更新从Hash表中查到的最后更新的价格。

StringBuilder.append()方法:在字符串结尾增加信息。

java.math.BigInteger:可以进行精度较高的数字计算。

注释!!!

代码展示

菜品类

菜品类我们需要保存每一种菜的基本信息:名字和价格。我们还需要计算不同菜品对应的不同份额的价格:小份(1)对应基本价格,中份(2)对应基本价格1.5,大份(3)对应基本价格2。

class Dish { String name;//菜名 int unit_price; //单价 int getPrice(int portion) {//计算菜品价格的方法 double price = portion * unit_price; if (portion == 2) { price=1.5; } else if (portion == 3) { price=2; } return new BigDecimal(price).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();//保留整数 } }

菜谱类

菜谱类包含在餐厅提供的所有菜品信息,我们可以用一个Dish数组进行保存,通过菜谱类中的菜品名称进行引用。我们需要实现两个方法:addDish()和findDish()。addDish()向菜单中添加新的菜品,同时更新如果当前的菜品名已经存在,将会被更新为新的价格;findDish()方法用于根据名字在菜单中进行查找,返回而对应菜品。这样我们可以通过菜品名称进行对应的价格更新

 类图:

 

 

7-5 面向对象编程(封装性)

Student类具体要求如下:
私有成员变量:学号(sid,String类型),姓名(name,String类型),年龄(age,int类型),专业(major,String类型) 。
提供无参构造和有参构造方法。(注意:有参构造方法中需要对年龄大小进行判定)
普通成员方法:print(),输出格式为“学号:6020203100,姓名:王宝强,年龄:21,专业:计算机科学与技术”。
普通成员方法:提供setXxx和getXxx方法。(注意:setAge()方法中需要对年龄进行判定)
注意:
年龄age不大于0,则不进行赋值。
print()中的“:”和“,”为均为中文冒号和逗号。

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}

/* 请在这里填写答案 */

 

输入格式:

输出格式:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程

输入样例:

在这里给出一组输入。例如:

6020203110 王宝强 21 计算机科学与技术
6020203119 张三丰 23 软件工程
 

输出样例:

在这里给出相应的输出。例如:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程
 
 代码如下:
 
复制代码
import java.util.Scanner;
class Student {
    private String sid;
    private String name;
    private int age;
    private String major;
    public Student() {
    }
    public Student(String sid, String name, int age, String major) {
        this.sid = sid;
        this.name = name;
        if(age > 0) {
            this.age = age;
        }
        this.major = major;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if(age > 0) {
            this.age = age;
        }
    }
    public String getMajor() {
        return major;
    }
    public void setMajor(String major) {
        this.major = major;
    }
    public void print(){
        System.out.println("学号:"+sid+",姓名:"+name+",年龄:"+age+",专业:"+major);
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}
复制代码

 

简要分析:

这个程序实现了一个简单的 Java 学生类。学生类具有私有实例变量来表示学生的ID、姓名、年龄和专业。它还有多个getter和setter方法来访问和修改这些变量。

该程序还包括一个 Main 类,它创建了两个 Student 对象。第一个对象使用无参数构造函数和 set 方法来设置实例变量。第二个对象使用四个参数的构造函数创建。

程序然后使用 Student 类的 print 方法打印出每个学生的信息。

总而言之,这个程序展示了 Java 中类、实例变量和构造函数的基本概念。

 

题目集五

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

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year-month-day
    
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year-month-day
    
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    天数值
    
     

输入样例1:

在这里给出一组输入。例如:

3 2014 2 14 2020 6 14
 

输出样例1:

在这里给出相应的输出。例如:

2312
 

输入样例2:

在这里给出一组输入。例如:

2 1935 2 17 125340
 

输出样例2:

在这里给出相应的输出。例如:

1591-12-17
 

输入样例3:

在这里给出一组输入。例如:

1 1999 3 28 6543
 

输出样例3:

在这里给出相应的输出。例如:

2017-2-24
 

输入样例4:

在这里给出一组输入。例如:

0 2000 5 12 30
 

输出样例4:

在这里给出相应的输出。例如:

Wrong Format

代码如下:

复制代码
import java.util.Scanner;

/**
 * 日期处理工具类
 */
class DateUtil {
    /**
     * 每个月对应的天数
     */
    private static final int[] DAYS_OF_MONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    /**
     * 计算某一年是否为闰年
     */
    static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }

    /**
     * 计算某一年某一月的天数
     */
    static int getDaysOfMonth(int year, int month) {
        if (month == 2 && isLeapYear(year)) {
            return 29;
        } else {
            return DAYS_OF_MONTH[month - 1];
        }
    }

   
    static boolean isValidDate(int year, int month, int day) {
        if (year < 1900 || year > 2050) {
            return false;
        }
        if (month < 1 || month > 12) {
            return false;
        }
        if (day < 1 || day > getDaysOfMonth(year, month)) {
            return false;
        }
        return true;
    }

    /**
 * 计算从某一天开始的n天后的日期
 */
static int[] getNextDate(int year, int month, int day, int n) {
    for (int i = 0; i < n; i++) {
        day++;
        if (day > getDaysOfMonth(year, month)) {
            day = 1;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
    }
    return new int[]{year, month, day};
}

/**
 * 计算从某一天开始的n天前的日期
 */
static int[] getPrevDate(int year, int month, int day, int n) {
    for (int i = 0; i < n; i++) {
        day--;
        if (day == 0) {
            month--;
            if (month == 0) {
                month = 12;
                year--;
            }
            day = getDaysOfMonth(year, month);
        }
    }
    return new int[]{year, month, day};
}
    /**
     * 计算两个日期相差的天数
     */
    static int getDaysBetweenDates(int year1, int month1, int day1, int year2, int month2, int day2) {
        int days = 0;
        if (year1 > year2) {
            int[] temp = {year1, month1, day1};
            year1 = year2;
            month1 = month2;
            day1 = day2;
            year2 = temp[0];
            month2 = temp[1];
            day2 = temp[2];
        }
        if (year1 == year2 && month1 > month2) {
            int[] temp = {year1, month1, day1};
            month1 = month2;
            day1 = day2;
            month2 = temp[1];
            day2 = temp[2];
        }
        while (true) {
            if (year1 == year2 && month1 == month2 && day1 == day2) {
                break;
            }
            days++;
            day1++;
            if (day1 > getDaysOfMonth(year1, month1)) {
                day1 = 1;
                month1++;
            }
            if (month1 > 12) {
                month1 = 1;
                year1++;
            }
        }
        return days;
    }
}

/**
 * 年份类
 */
class Year {
    private int year;

    /**
     * 构造函数
     */
    Year(int year) {
        this.year = year;
    }

    /**
     * 闰年天数
     */
    int getDaysOfLeapYear() {
        return 366;
    }

    /**
     * 非闰年天数
     */
    int getDaysOfNonLeapYear() {
        return 365;
    }

    /**
     * 是否为闰年
     */
    boolean isLeapYear() {
        return DateUtil.isLeapYear(year);
    }
}

/**
 * 月份类
 */
class Month {
    private int year;
    private int month;

    /**
     * 构造函数
     */
    Month(int year, int month) {
        this.year = year;
        this.month = month;
    }

    /**
     * 当前月份的天数
     */
    int getDaysOfMonth() {
        return DateUtil.getDaysOfMonth(year, month);
    }
}

/**
 * 日份类
 */
class Day {
    private int year;
    private int month;
    private int day;

    /**
     * 构造函数
     */
    Day(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    /**
     * 下n天的日期
     */
    int[] getNextDate(int n) {
        return DateUtil.getNextDate(year, month, day, n);
    }

    /**
     * 前n天的日期
     */
    int[] getPrevDate(int n) {
        return DateUtil.getPrevDate(year, month, day, n);
    }
}

/**
 * 主类
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int op = scanner.nextInt();
        switch (op) {
            case 1:
                int year1 = scanner.nextInt();
                int month1 = scanner.nextInt();
                int day1 = scanner.nextInt();
                int n1 = scanner.nextInt();
                if (DateUtil.isValidDate(year1, month1, day1)) {
                    int[] nextDate = new Day(year1, month1, day1).getNextDate(n1);
                    System.out.println(nextDate[0] + "-" + nextDate[1] + "-" + nextDate[2]);
                } else {
                    System.out.println("Wrong Format");
                }
                break;
            case 2:
                int year2 = scanner.nextInt();
                int month2 = scanner.nextInt();
                int day2 = scanner.nextInt();
                int n2 = scanner.nextInt();
                if (DateUtil.isValidDate(year2, month2, day2)) {
                    int[] prevDate = new Day(year2, month2, day2).getPrevDate(n2);
                    System.out.println(prevDate[0] + "-" + prevDate[1] + "-" + prevDate[2]);
                } else {
                    System.out.println("Wrong Format");
                }
                break;
            case 3:
                int year3 = scanner.nextInt();
                int month3 = scanner.nextInt();
                int day3 = scanner.nextInt();
                int year4 = scanner.nextInt();
                int month4 = scanner.nextInt();
                int day4 = scanner.nextInt();
                if (DateUtil.isValidDate(year3, month3, day3) && DateUtil.isValidDate(year4, month4, day4)) {
                    System.out.println(DateUtil.getDaysBetweenDates(year3, month3, day3, year4, month4, day4));
                } else {
                    System.out.println("Wrong Format");
                }
                break;
            default:
                System.out.println("Wrong Format");
                break;
        }
    }
}
复制代码

 

简要分析:

这是一个日期处理工具类和一些日期相关的类,还有一个主类来调用日期处理的方法。代码提供了计算两个日期之间相差的天数、计算某个日期的下n天的日期、计算某个日期的前n天的日期等常见日期处理功能。

其中,DateUtil是日期处理的主要类,包含了一些静态方法来处理日期相关的问题,例如验证日期格式、计算某个日期是否是闰年、计算某个日期的月份的天数、计算两个日期之间相差的天数、计算某个日期的下n天的日期、计算某个日期的前n天的日期等等。

同时,代码也提供了一些日期相关的类,例如Year表示年份,Month表示月份,Day表示日期,这些类可以根据实际需要来添加或者修改。主类提供了一个菜单,根据用户的输入来调用相应的方法来处理日期问题。

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

 

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year1-month1-day1 next n days is:year2-month2-day2
    
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year1-month1-day1 previous n days is:year2-month2-day2
    
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    The days between year1-month1-day1 and year2-month2-day2 are:值
    
     

输入样例1:

在这里给出一组输入。例如:

3 2014 2 14 2020 6 14
 

输出样例1:

在这里给出相应的输出。例如:

The days between 2014-2-14 and 2020-6-14 are:2312
 

输入样例2:

在这里给出一组输入。例如:

2 1834 2 17 7821
 

输出样例2:

在这里给出相应的输出。例如:

1834-2-17 previous 7821 days is:1812-9-19
 

输入样例3:

在这里给出一组输入。例如:

1 1999 3 28 6543
 

输出样例3:

在这里给出相应的输出。例如:

1999-3-28 next 6543 days is:2017-2-24
 

输入样例4:

在这里给出一组输入。例如:

0 2000 5 12 30
 

输出样例4:

在这里给出相应的输出。例如:

Wrong Format

代码如下:

复制代码
import java.util.Scanner;

/**
 * 日期处理工具类
 */
class DateUtil {
    /**
     * 每个月对应的天数
     */
    private static final int[] DAYS_OF_MONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    /**
     * 计算某一年是否为闰年
     */
    static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }

    /**
     * 计算某一年某一月的天数
     */
    static int getDaysOfMonth(int year, int month) {
        if (month == 2 && isLeapYear(year)) {
            return 29;
        }
        else if(month == 2 && !isLeapYear(year)){
            return 28;
        }
        else {
            return DAYS_OF_MONTH[month - 1];
        }
    }

    
    static boolean isValidDate(int year, int month, int day) {
        if (year < 1900 || year > 2050) {
            return false;
        }
        if (month < 1 || month > 12) {
            return false;
        }
        if (day < 1 || day > getDaysOfMonth(year, month)) {
            return false;
        }
        return true;
    }

    /**
 * 计算从某一天开始的n天后的日期
 */
static int[] getNextDate(int year, int month, int day, int n) {
    for (int i = 0; i < n; i++) {
        day++;
        if (day > getDaysOfMonth(year, month)) {
            day = 1;
            month++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
    }
    return new int[]{year, month, day};
}

/**
 * 计算从某一天开始的n天前的日期
 */
static int[] getPrevDate(int year, int month, int day, int n) {
    for (int i = 0; i < n; i++) {
        day--;
        if (day == 0) {
            month--;
            if (month == 0) {
                month = 12;
                year--;
            }
            day = getDaysOfMonth(year, month);
        }
    }
    return new int[]{year, month, day};
}
    /**
     * 计算两个日期相差的天数
     */
    static int getDaysBetweenDates(int year1, int month1, int day1, int year2, int month2, int day2) {
        int days = 0;
        if (year1 > year2) {
            int[] temp = {year1, month1, day1};
            year1 = year2;
            month1 = month2;
            day1 = day2;
            year2 = temp[0];
            month2 = temp[1];
            day2 = temp[2];
        }
        if (year1 == year2 && month1 > month2) {
            int[] temp = {year1, month1, day1};
            month1 = month2;
            day1 = day2;
            month2 = temp[1];
            day2 = temp[2];
        }
        while (true) {
            if (year1 == year2 && month1 == month2 && day1 == day2) {
                break;
            }
            days++;
            day1++;
            if (day1 > getDaysOfMonth(year1, month1)) {
                day1 = 1;
                month1++;
            }
            if (month1 > 12) {
                month1 = 1;
                year1++;
            }
        }
        return days;
    }
}

/**
 * 年份类
 */
class Year {
    private int year;

    /**
     * 构造函数
     */
    Year(int year) {
        this.year = year;
    }

    /**
     * 闰年天数
     */
    int getDaysOfLeapYear() {
        return 366;
    }

    /**
     * 非闰年天数
     */
    int getDaysOfNonLeapYear() {
        return 365;
    }

    /**
     * 是否为闰年
     */
    boolean isLeapYear() {
        return DateUtil.isLeapYear(year);
    }
}

/**
 * 月份类
 */
class Month {
    private int year;
    private int month;

    /**
     * 构造函数
     */
    Month(int year, int month) {
        this.year = year;
        this.month = month;
    }

    /**
     * 当前月份的天数
     */
    int getDaysOfMonth() {
        return DateUtil.getDaysOfMonth(year, month);
    }
}

/**
 * 日份类
 */
class Day {
    private int year;
    private int month;
    private int day;

    /**
     * 构造函数
     */
    Day(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    /**
     * 下n天的日期
     */
    int[] getNextDate(int n) {
        return DateUtil.getNextDate(year, month, day, n);
    }

    /**
     * 前n天的日期
     */
    int[] getPrevDate(int n) {
        return DateUtil.getPrevDate(year, month, day, n);
    }
}

/**
 * 主类
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int op = scanner.nextInt();
        switch (op) {
            case 1:
                int year1 = scanner.nextInt();
                int month1 = scanner.nextInt();
                int day1 = scanner.nextInt();
                int n1 = scanner.nextInt();
                if (DateUtil.isValidDate(year1, month1, day1)) {
                    int[] nextDate = new Day(year1, month1, day1).getNextDate(n1);
                    System.out.print(year1 + "-" + month1 + "-" + day1 + " next " + n1 +" "+ "days is:");
                    System.out.print(nextDate[0] + "-" + nextDate[1] + "-" + nextDate[2]);
                } else {
                    System.out.println("Wrong Format");
                }
                break;
            case 2:
                int year2 = scanner.nextInt();
                int month2 = scanner.nextInt();
                int day2 = scanner.nextInt();
                int n2 = scanner.nextInt();
                if (DateUtil.isValidDate(year2, month2, day2)) {
                    int[] prevDate = new Day(year2, month2, day2).getPrevDate(n2);
                    System.out.print(year2 + "-" + month2 + "-" + day2 + " previous " + n2 +" "+ "days is:");
                    System.out.print(prevDate[0] + "-" + prevDate[1] + "-" + prevDate[2]);
                } else {
                    System.out.println("Wrong Format");
                }
                break;
            case 3:
                int year3 = scanner.nextInt();
                int month3 = scanner.nextInt();
                int day3 = scanner.nextInt();
                int year4 = scanner.nextInt();
                int month4 = scanner.nextInt();
                int day4 = scanner.nextInt();
                if (DateUtil.isValidDate(year3, month3, day3) && DateUtil.isValidDate(year4, month4, day4)) {
                    System.out.print("The days between " + year3 + "-" + month3 + "-" + day3 + " "+"and"+ " ");
                    System.out.print(year4 + "-" + month4 + "-" + day4+" " + "are:");
                    System.out.print(DateUtil.getDaysBetweenDates(year3, month3, day3, year4, month4, day4));
                } else {
                    System.out.println("Wrong Format");
                }
                break;
            default:
                System.out.println("Wrong Format");
                break;
        }
    }
}
复制代码

 

 简要分析:和7-5差不多
 
第六次作业
 
7-4ATM机类结构设计(一)
 
 

设计ATM仿真系统,具体要求参见作业说明。
OO作业8-1题目说明.pdf

输入格式:

每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:

  • 存款、取款功能输入数据格式:
    卡号 密码 ATM机编号 金额(由一个或多个空格分隔),
    其中,当金额大于0时,代表取款,否则代表存款。
  • 查询余额功能输入数据格式:
    卡号

输出格式:

①输入错误处理

  • 如果输入卡号不存在,则输出Sorry,this card does not exist.
  • 如果输入ATM机编号不存在,则输出Sorry,the ATM's id is wrong.
  • 如果输入银行卡密码错误,则输出Sorry,your password is wrong.
  • 如果输入取款金额大于账户余额,则输出Sorry,your account balance is insufficient.
  • 如果检测为跨行存取款,则输出Sorry,cross-bank withdrawal is not supported.

②取款业务输出

输出共两行,格式分别为:

[用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

③存款业务输出

输出共两行,格式分别为:

[用户姓名]在[银行名称]的[ATM编号]上存款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

④查询余额业务输出

¥[金额]

金额保留两位小数。

输入样例1:

在这里给出一组输入。例如:

6222081502001312390 88888888 06 -500.00
#
 

输出样例1:

在这里给出相应的输出。例如:

张无忌在中国工商银行的06号ATM机上存款¥500.00
当前余额为¥10500.00
 

输入样例2:

在这里给出一组输入。例如:

6217000010041315709  88888888 02 3500.00
#
 

输出样例2:

在这里给出相应的输出。例如:

杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥6500.00
 

输入样例3:

在这里给出一组输入。例如:

6217000010041315715
#
 

输出样例3:

在这里给出相应的输出。例如:

¥10000.00
 

输入样例4:

在这里给出一组输入。例如:

6222081502001312390 88888888 06 -500.00
6222081502051320786 88888888 06 1200.00
6217000010041315715 88888888 02 1500.00
6217000010041315709  88888888 02 3500.00
6217000010041315715
#
 

输出样例4:

在这里给出相应的输出。例如:

张无忌在中国工商银行的06号ATM机上存款¥500.00
当前余额为¥10500.00
韦小宝在中国工商银行的06号ATM机上取款¥1200.00
当前余额为¥8800.00
杨过在中国建设银行的02号ATM机上取款¥1500.00
当前余额为¥8500.00
杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥5000.00
¥5000.00

代码如下:

复制代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

class ChinaUnionPay {
    // 中国银联类
    private String name; // 名称
    private List<Bank> bankList; // 银行列表

    ChinaUnionPay(String name) {
        this.name = name;
        this.bankList = new ArrayList<>();
    }

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

    public String getName() {
        return name;
    }

    public void addBank(Bank bank) {
        bankList.add(bank);
    }

    public Bank findBank(String bankName) {
        for (Bank bank : bankList) {
            if (bank.getName().equals(bankName)) {
                return bank;
            }
        }
        return null;
    }
}

class Bank {
    // 银行类
    private String name; // 名称
    private ChinaUnionPay chinaUnionPay; // 所属中国银联
    private List<BankAccount> accountList; // 账户列表
    private Map<String, ATM> atmMap; // ATM机列表

    Bank(String name, ChinaUnionPay chinaUnionPay) {
        this.name = name;
        this.chinaUnionPay = chinaUnionPay;
        this.accountList = new ArrayList<>();
        this.atmMap = new HashMap<>();
        chinaUnionPay.addBank(this);
    }

    public List<BankAccount> getAccountList() {
        return accountList;
   }
   

    public String getName() {
        return name;
    }

    public ChinaUnionPay getChinaUnionPay() {
        return chinaUnionPay;
    }


    public void addAccount(BankAccount account) {
        accountList.add(account);
    }

    public BankAccount findAccount(String accountNumber) {
        for (BankAccount account : accountList) {
            if (account.getAccountNumber().equals(accountNumber)) {
                return account;
            }
        }
        return null;
    }

    public void addATM(ATM atm) {
        atmMap.put(atm.getId(), atm);
    }

    public ATM findATM(String atmId) {
        return atmMap.get(atmId);
    }
 

}

class BankUser {
    // 银行用户类
    private String name; // 姓名
    private Bank bank; // 所属银行
    private List<BankCard> cardList; // 银行卡列表

    BankUser(String name, Bank bank) {
        this.name = name;
        this.bank = bank;
        this.cardList = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public Bank getBank() {
        return bank;
    }

    public void addCard(BankCard card) {
        cardList.add(card);
    }

    public BankCard findCard(String cardNumber) {
        for (BankCard card : cardList) {
            if (card.getCardNumber().equals(cardNumber)) {
                return card;
            }
        }
        return null;
    }
}

class BankAccount {
    // 银行账户类
    private String accountNumber; // 账号
    private BankUser user; // 所属银行用户
    private double balance; // 余额

    BankAccount(String accountNumber, BankUser user, double balance) {
        this.accountNumber = accountNumber;
        this.user = user;
        this.balance = balance;
        user.addCard(new BankCard(accountNumber, "88888888"));
        user.getBank().addAccount(this);
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public BankUser getUser() {
        return user;
    }

    public double getBalance() {
        return balance;
    }

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

    public void showInfo(String operateType, String atmId, String operateMoneyString) {
        double operateMoney = Double.parseDouble(operateMoneyString);
        String sign = operateMoney > 0 ? "存款" : "取款";
        String absOperateMoneyString = String.format("%.2f", Math.abs(operateMoney));

        System.out.println(user.getName() + "在" + user.getBank().getName() + "的" + atmId + "号ATM机上" +
                sign + "¥" + absOperateMoneyString);
        System.out.println("当前余额为¥" + String.format("%.2f", balance));
    }
}

class BankCard {
    // 银行卡类
    private String cardNumber; // 卡号
    private String password; // 密码
    private BankAccount account; // 所属银行账户

    BankCard(String cardNumber, String password) {
        this.cardNumber = cardNumber;
        this.password = password;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public String getPassword() {
        return password;
    }

    public BankAccount getAccount() {
        return account;
    }

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

class ATM {
    // ATM类
    private String id; // 编号
    private Bank bank; // 所属银行

    ATM(String id, Bank bank) {
        this.id = id;
        this.bank = bank;
        bank.addATM(this);
    }

    public String getId() {
        return id;
    }

    public Bank getBank() {
        return bank;
    }
}
public class Main { public static void main(String[] args) { //初始化中国银联 ChinaUnionPay chinaUnionPay = new ChinaUnionPay("中国银联");
    ChinaUnionPay chinaUnionPay = new ChinaUnionPay("中国银联");
    //初始化银行和ATM机
    Bank bank1 = new Bank("中国建设银行", chinaUnionPay);
    ATM atm1 = new ATM("01", bank1);
    ATM atm2 = new ATM("02", bank1);
    ATM atm3 = new ATM("03", bank1);
    ATM atm4 = new ATM("04", bank1);
    Bank bank2 = new Bank("中国工商银行", chinaUnionPay);
    ATM atm5 = new ATM("05", bank2);
    ATM atm6 = new ATM("06", bank2);
    //初始化用户和账户
    BankUser user1 = new BankUser("杨过", bank1);
    BankAccount account1 = new BankAccount("3217000010041315709", user1, 10000.00);
    BankCard card1 = new BankCard("6217000010041315709", "88888888");
    card1.setAccount(account1);
    user1.addCard(card1);
    BankCard card2 = new BankCard("6217000010041315715", "88888888");
    card2.setAccount(account1);
    user1.addCard(card2);
    BankAccount account2 = new BankAccount("3217000010041315715", user1, 10000.00);
    BankCard card3 = new BankCard("6217000010041315718", "88888888");
    card3.setAccount(account2);
    user1.addCard(card3);
    BankUser user2 = new BankUser("郭靖", bank1);
    BankAccount account3 = new BankAccount("3217000010051320007", user2, 10000.00);
    BankCard card4 = new BankCard("6217000010051320007", "88888888");
    card4.setAccount(account3);
    user2.addCard(card4);
    BankUser user3 = new BankUser("张无忌", bank2);
    BankAccount account4 = new BankAccount("3222081502001312389", user3, 10000.00);
    BankCard card5 = new BankCard("6222081502001312389", "88888888");
    card5.setAccount(account4);
    user3.addCard(card5);
    BankAccount account5 = new BankAccount("3222081502001312390", user3, 10000.00);
    BankCard card6 = new BankCard("6222081502001312390", "88888888");
    card6.setAccount(account5);
    user3.addCard(card6);
    BankAccount account6 = new BankAccount("3222081502001312399", user3, 10000.00);
    BankCard card7 = new BankCard("6222081502001312399", "88888888");
    card7.setAccount(account6);
    user3.addCard(card7);
    BankCard card8 = new BankCard("6222081502001312400", "88888888");
    card8.setAccount(account6);
    user3.addCard(card8);
    BankUser user4 = new BankUser("韦小宝", bank2);
    BankAccount account7 = new BankAccount("3222081502051320785", user4, 10000.00);
    BankCard card9 = new BankCard("6222081502051320785", "88888888");
    card9.setAccount(account7);
    user4.addCard(card9);
    BankAccount account8 = new BankAccount("3222081502051320786", user4, 10000.00);
    BankCard card10 = new BankCard("6222081502051320786", "88888888");
    card10.setAccount(account8);
    user4.addCard(card10);
    //输入输出交互
    Scanner scanner = new Scanner(System.in);
    while (true) {
        String input = scanner.nextLine();
        if (input.equals("#")) {
            break;
        }
        String[] splitInput = input.split(" ");
        String cardNumber = splitInput[0];
        BankCard card = null;
        boolean cardExist = false;
        for (Bank bank : chinaUnionPay.getBankList()) {
    for (BankAccount account : bank.getAccountList()) {
        BankUser user = account.getUser();
        card = user.findCard(cardNumber);
        if (card != null) {
            cardExist = true;
            break;
        }
    }
    if (cardExist) {
        break;
    }
}

        if (!cardExist) {
            System.out.println("Sorry,this card does not exist.");
            continue;
        }
        String password = splitInput[1];
        if (!password.equals("88888888")) {
            System.out.println("Sorry,your password is wrong.");
            continue;
        }
        String atmId = splitInput[2];
        ATM atm = card.getAccount().getUser().getBank().findATM(atmId);
        if (atm == null) {
            System.out.println("Sorry,the ATM's id is wrong.");
            continue;
        }
        if (splitInput.length == 3) {
            // Query
            System.out.println("¥" + String.format("%.2f", card.getAccount().getBalance()));
        } else {
            // Withdraw / Deposit
            double amount = Double.parseDouble(splitInput[3]);
            if (amount > 0) {
                // Withdraw
                if (amount > card.getAccount().getBalance()) {
                    System.out.println("Sorry,your account balance is insufficient.");
                    continue;
                }
                if (card.getAccount().getUser().getBank() != atm.getBank()) {
                    System.out.println("Sorry,cross-bank withdrawal is not supported.");
                    continue;
                }
                card.getAccount().setBalance(card.getAccount().getBalance() - amount);
                card.getAccount().showInfo("取款", atm.getId(), String.format("%.2f", -amount));
            } else {
                // Deposit
                amount = -amount;
                if (card.getAccount().getUser().getBank() != atm.getBank()) {
                    System.out.println("Sorry,cross-bank deposit is not supported.");
                    continue;
                }
                card.getAccount().setBalance(card.getAccount().getBalance() + amount);
                card.getAccount().showInfo("存款", atm.getId(), String.format("%.2f", amount));
            }
        }
    }
}
}
复制代码

简要分析:代码实现的功能是一个简单的银行自动柜员机系统,包括了中国银联、银行、用户、账户、银行卡、自动柜员机六个类,具体实现了查询余额、存款、取款等操作。代码中主要用了列表和映射这两种数据结构来存储和管理数据。同时,在输出交互的部分,使用了简单的输入输出流和字符串处理方法来实现用户和系统之间的交互。

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

设计ATM仿真系统,具体要求参见作业说明。
OO作业9-1题目说明.pdf

输入格式:

每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:

  • 取款功能输入数据格式:
    卡号 密码 ATM机编号 金额(由一个或多个空格分隔)
  • 查询余额功能输入数据格式:
    卡号

输出格式:

①输入错误处理

  • 如果输入卡号不存在,则输出Sorry,this card does not exist.
  • 如果输入ATM机编号不存在,则输出Sorry,the ATM's id is wrong.
  • 如果输入银行卡密码错误,则输出Sorry,your password is wrong.
  • 如果输入取款金额大于账户余额,则输出Sorry,your account balance is insufficient.

②取款业务输出

输出共两行,格式分别为:

业务:取款 [用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

③查询余额业务输出

业务:查询余额 ¥[金额]

金额保留两位小数。

输入样例1:

在这里给出一组输入。例如:

6222081502001312390 88888888 06 500.00
#
 

输出样例1:

在这里给出相应的输出。例如:

业务:取款 张无忌在中国工商银行的06号ATM机上取款¥500.00
当前余额为¥9500.00
 

输入样例2:

在这里给出一组输入。例如:

6217000010041315709  88888888 06 3500.00
#
 

输出样例2:

在这里给出相应的输出。例如:

业务:取款 杨过在中国工商银行的06号ATM机上取款¥3500.00
当前余额为¥6395.00
 

输入样例3:

在这里给出一组输入。例如:

6217000010041315715
#
 

输出样例3:

在这里给出相应的输出。例如:

业务:查询余额 ¥10000.00
 

输入样例4:

在这里给出一组输入。例如:

6222081502001312390 88888888 01 500.00
6222081502051320786 88888888 06 1200.00
6217000010041315715 88888888 02 1500.00
6217000010041315709  88888888 02 3500.00
6217000010041315715
#
 

输出样例4:

在这里给出相应的输出。例如:

业务:取款 张无忌在中国建设银行的01号ATM机上取款¥500.00
当前余额为¥9490.00
业务:取款 韦小宝在中国工商银行的06号ATM机上取款¥1200.00
当前余额为¥8800.00
业务:取款 杨过在中国建设银行的02号ATM机上取款¥1500.00
当前余额为¥8500.00
业务:取款 杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥5000.00
业务:查询余额 ¥5000.00
 

输入样例5:

在这里给出一组输入。例如:

6640000010045442002 88888888 09 3000
6640000010045442002 88888888 06 8000
6640000010045442003 88888888 01 10000
6640000010045442002
#
 

输出样例5:

在这里给出相应的输出。例如:

业务:取款 张三丰在中国农业银行的09号ATM机上取款¥3000.00
当前余额为¥6880.00
业务:取款 张三丰在中国工商银行的06号ATM机上取款¥8000.00
当前余额为¥-1416.00
业务:取款 张三丰在中国建设银行的01号ATM机上取款¥10000.00
当前余额为¥-11916.00
业务:查询余额 ¥-11916.00

代码如下:

复制代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

class ChinaUnionPay {
    // 中国银联类
    private String name; // 名称
    private List<Bank> bankList; // 银行列表

    ChinaUnionPay(String name) {
        this.name = name;
        this.bankList = new ArrayList<>();
    }

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

    public String getName() {
        return name;
    }

    public void addBank(Bank bank) {
        bankList.add(bank);
    }

    public Bank findBank(String bankName) {
        for (Bank bank : bankList) {
            if (bank.getName().equals(bankName)) {
                return bank;
            }
        }
        return null;
    }
}

class Bank {
    // 银行类
    private String name; // 名称
    private ChinaUnionPay chinaUnionPay; // 所属中国银联
    private List<BankAccount> accountList; // 账户列表
    private Map<String, ATM> atmMap; // ATM机列表

    Bank(String name, ChinaUnionPay chinaUnionPay) {
        this.name = name;
        this.chinaUnionPay = chinaUnionPay;
        this.accountList = new ArrayList<>();
        this.atmMap = new HashMap<>();
        chinaUnionPay.addBank(this);
    }

    public List<BankAccount> getAccountList() {
        return accountList;
   }
   

    public String getName() {
        return name;
    }

    public ChinaUnionPay getChinaUnionPay() {
        return chinaUnionPay;
    }


    public void addAccount(BankAccount account) {
        accountList.add(account);
    }

    public BankAccount findAccount(String accountNumber) {
        for (BankAccount account : accountList) {
            if (account.getAccountNumber().equals(accountNumber)) {
                return account;
            }
        }
        return null;
    }

    public void addATM(ATM atm) {
        atmMap.put(atm.getId(), atm);
    }

    public ATM findATM(String atmId) {
        return atmMap.get(atmId);
    }

}

class BankUser {
    // 银行用户类
    private String name; // 姓名
    private Bank bank; // 所属银行
    private List<BankCard> cardList; // 银行卡列表

    BankUser(String name, Bank bank) {
        this.name = name;
        this.bank = bank;
        this.cardList = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public Bank getBank() {
        return bank;
    }

    public void addCard(BankCard card) {
        cardList.add(card);
    }

    public BankCard findCard(String cardNumber) {
        for (BankCard card : cardList) {
            if (card.getCardNumber().equals(cardNumber)) {
                return card;
            }
        }
        return null;
    }
}

class BankAccount {
    // 银行账户类
    private String accountNumber; // 账号
    private BankUser user; // 所属银行用户
    private double balance; // 余额
    private String classes; //种类
    BankAccount(String accountNumber, BankUser user, double balance, String classes) {
        this.accountNumber = accountNumber;
        this.user = user;
        this.balance = balance;
        this.classes = classes; 
        user.addCard(new BankCard(accountNumber, "88888888"));
        user.getBank().addAccount(this);
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public BankUser getUser() {
        return user;
    }

    public double getBalance() {
        return balance;
    }

    public String getClasses(){
        return classes;
    }

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

    public void showInfo(String operateType, String atmId, String operateMoneyString) {
        double operateMoney = Double.parseDouble(operateMoneyString);
        String sign = operateMoney > 0 ? "存款" : "取款";
        String absOperateMoneyString = String.format("%.2f", Math.abs(operateMoney));

        System.out.println("业务:"+sign+user.getName() + "在" + user.getBank().getName() + "的" + atmId + "号ATM机上" +
                sign + "¥" + absOperateMoneyString);
        System.out.println("当前余额为¥" + String.format("%.2f", balance));
    }
}

class BankCard {
    // 银行卡类
    private String cardNumber; // 卡号
    private String password; // 密码
    private BankAccount account; // 所属银行账户

    BankCard(String cardNumber, String password) {
        this.cardNumber = cardNumber;
        this.password = password;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public String getPassword() {
        return password;
    }

    public BankAccount getAccount() {
        return account;
    }

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

class ATM {
    // ATM类
    private String id; // 编号
    private Bank bank; // 所属银行

    ATM(String id, Bank bank) {
        this.id = id;
        this.bank = bank;
        bank.addATM(this);
    }

    public String getId() {
        return id;
    }

    public Bank getBank() {
        return bank;
    }
}
public class Main { public static void main(String[] args) { //初始化中国银联 ChinaUnionPay chinaUnionPay = new ChinaUnionPay("中国银联");
    ChinaUnionPay chinaUnionPay = new ChinaUnionPay("中国银联");
    //初始化银行和ATM机
    Bank bank1 = new Bank("中国建设银行", chinaUnionPay);
    ATM atm1 = new ATM("01", bank1);
    ATM atm2 = new ATM("02", bank1);
    ATM atm3 = new ATM("03", bank1);
    ATM atm4 = new ATM("04", bank1);
    Bank bank2 = new Bank("中国工商银行", chinaUnionPay);
    ATM atm5 = new ATM("05", bank2);
    ATM atm6 = new ATM("06", bank2);
    Bank bank3 = new Bank("中国农业银行", chinaUnionPay);
    ATM atm7 = new ATM("07", bank3);
    ATM atm8 = new ATM("08", bank3);
    ATM atm9 = new ATM("09", bank3);
    ATM atm10 = new ATM("10", bank3);
    ATM atm11 = new ATM("11", bank3);
    //初始化用户和账户
    BankUser user1 = new BankUser("杨过", bank1);
    BankAccount account1 = new BankAccount("3217000010041315709", user1, 10000.00,"借记账号");
    BankCard card1 = new BankCard("6217000010041315709", "88888888");
    card1.setAccount(account1);
    user1.addCard(card1);
    BankCard card2 = new BankCard("6217000010041315715", "88888888");
    card2.setAccount(account1);
    user1.addCard(card2);
    BankAccount account2 = new BankAccount("3217000010041315715", user1, 10000.00,"借记账号");
    BankCard card3 = new BankCard("6217000010041315718", "88888888");
    card3.setAccount(account2);
    user1.addCard(card3);
    BankUser user2 = new BankUser("郭靖", bank1);
    BankAccount account3 = new BankAccount("3217000010051320007", user2, 10000.00,"借记账号");
    BankCard card4 = new BankCard("6217000010051320007", "88888888");
    card4.setAccount(account3);
    user2.addCard(card4);
    BankUser user3 = new BankUser("张无忌", bank2);
    BankAccount account4 = new BankAccount("3222081502001312389", user3, 10000.00,"借记账号");
    BankCard card5 = new BankCard("6222081502001312389", "88888888");
    card5.setAccount(account4);
    user3.addCard(card5);
    BankAccount account5 = new BankAccount("3222081502001312390", user3, 10000.00,"借记账号");
    BankCard card6 = new BankCard("6222081502001312390", "88888888");
    card6.setAccount(account5);
    user3.addCard(card6);
    BankAccount account6 = new BankAccount("3222081502001312399", user3, 10000.00,"借记账号");
    BankCard card7 = new BankCard("6222081502001312399", "88888888");
    card7.setAccount(account6);
    user3.addCard(card7);
    BankCard card8 = new BankCard("6222081502001312400", "88888888");
    card8.setAccount(account6);
    user3.addCard(card8);
    BankUser user4 = new BankUser("韦小宝", bank2);
    BankAccount account7 = new BankAccount("3222081502051320785", user4, 10000.00,"借记账号");
    BankCard card9 = new BankCard("6222081502051320785", "88888888");
    card9.setAccount(account7);
    user4.addCard(card9);
    BankAccount account8 = new BankAccount("3222081502051320786", user4, 10000.00,"借记账号");
    BankCard card10 = new BankCard("6222081502051320786", "88888888");
    card10.setAccount(account8);
    user4.addCard(card10);
    BankUser user5 = new BankUser("张三丰", bank1);
    BankAccount account9 = new BankAccount("3640000010045442002", user5, 10000.00,"贷记账号");
    BankCard card11 = new BankCard("6640000010045442002", "88888888");
    card11.setAccount(account9);
    user5.addCard(card11);
    BankCard card12 = new BankCard("6640000010045442003", "88888888");
    card12.setAccount(account9);
    user5.addCard(card12);
    BankUser user6 = new BankUser("令狐冲", bank2);
    BankAccount account10 = new BankAccount("3640000010045441009", user5, 10000.00,"贷记账号");
    BankCard card13 = new BankCard("6640000010045441009", "88888888");
    card13.setAccount(account10);
    user6.addCard(card13);
    BankUser user7 = new BankUser("乔峰", bank3);
    BankAccount account11 = new BankAccount("3630000010033431001", user5, 10000.00,"贷记账号");
    BankCard card14 = new BankCard("6630000010033431001", "88888888");
    card14.setAccount(account11);
    user7.addCard(card14);
    //输入输出交互
    Scanner scanner = new Scanner(System.in);
    while (true) {
        String input = scanner.nextLine();
        if (input.equals("#")) {
            break;
        }
        String[] splitInput = input.split(" ");
        String cardNumber = splitInput[0];
        BankCard card = null;
        boolean cardExist = false;
        for (Bank bank : chinaUnionPay.getBankList()) {
    for (BankAccount account : bank.getAccountList()) {
        BankUser user = account.getUser();
        card = user.findCard(cardNumber);
        if (card != null) {
            cardExist = true;
            break;
        }
    }
    if (cardExist) {
        break;
    }
}

        if (!cardExist) {
            System.out.println("Sorry,this card does not exist.");
            continue;
        }
        String password = splitInput[1];
        if (!password.equals("88888888")) {
            System.out.println("Sorry,your password is wrong.");
            continue;
        }
        String atmId = splitInput[2];
        ATM atm = card.getAccount().getUser().getBank().findATM(atmId);
        if (atm == null) {
            System.out.println("Sorry,the ATM's id is wrong.");
            continue;
        }
        if (splitInput.length == 3) {
            // Query
            System.out.println("¥" + String.format("%.2f", card.getAccount().getBalance()));
        } else {
            // Withdraw / Deposit
            double amount = Double.parseDouble(splitInput[3]);
            if (amount > 0) {
                // Withdraw
                if (amount > card.getAccount().getBalance()) {
                    System.out.println("Sorry,your account balance is insufficient.");
                    continue;
                }
                if (card.getAccount().getUser().getBank() != atm.getBank()) {
                    System.out.println("Sorry,cross-bank withdrawal is not supported.");
                    continue;
                }
                card.getAccount().setBalance(card.getAccount().getBalance() - amount);
                card.getAccount().showInfo("取款", atm.getId(), String.format("%.2f", -amount));
            } else {
                // Deposit
                amount = -amount;
                if (card.getAccount().getUser().getBank() != atm.getBank()) {
                    System.out.println("Sorry,cross-bank deposit is not supported.");
                    continue;
                }
                card.getAccount().setBalance(card.getAccount().getBalance() + amount);
                card.getAccount().showInfo("存款", atm.getId(), String.format("%.2f", amount));
            }
        }
    }

}
}
复制代码

代码分析:和上面的差不多

踩坑心得

1:代码量较少,遇到长代码搞不定

拿atm类的题目来讲,我第一次没按6个实体类来设计,只写了两个类,类图如下

 

 

我后来改为了六个类,但是过程比较艰难且并没有全对

类图如下:

 

 

 

结果

 改进建议

1,平时多抽出时间来练,现在和别人差距有点大,pta做的时间比别人要久很多,感觉心态也不是很稳,可能需要一长段时间来系统性补强

 2,学习别人的代码风格,自己写多类时,函数还有各类之间的多态以及继承都是蒙的,写的时候非常混乱,感觉离开类图和个傻子样的

总结

这三次作业较上三次,难度有明显的提升,特别是代码数量上有明显的提升,而我目前还有些无法应对,学的很吃力,希望自己能够赶上大部队,尽快赶上,争取尽快搞明白多态和继承,同时在课堂上也希望自己反应能快点跟上老师现在讲的上层设计


posted @   grafspee  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示