OOP4-6次作业总结BLOG

OOP4-6次作业总结BLOG

22201303-范宇

前言

三次题目集中,对我个人而言,第5次较为简单,第四次和第六次有两道题比较困难,三次题目集总的来说具备一定的挑战性,挺适合我。

第四次和第五次题目集均给了提示,类的结构基本都设计好了,我们要做的只是填空;而第六次题目集的后两道题没有提示,需要自己设计类。

设计与分析

题目集四

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+英文空格+桌号+“:”+英文空格+当前桌的总价

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


import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.lang.*;
public class Main{
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String dish = input.nextLine();
        String[] name = dish.split(" ");
        ArrayList<Dish> ds = new ArrayList<>();

        while (name[0].compareTo("table") != 0) {
            int unit_price = Integer.parseInt(name[1]);
            Dish dish1 = new Dish(name[0], unit_price);
            int i;
            for(i=0;i<ds.size();i++){
                if(ds.get(i).getName().compareTo(name[0])==0){
                    break;
                }
            }
            if(i==ds.size()) ds.add(dish1);
            else {
                //ds.remove(i);
                ds.set(i,dish1);
            }
            //menu.addDish(name[0],unit_price);
            dish = input.nextLine();
            name = dish.split(" ");
            if(name[0].equals("end"))
                break;
        }
        Menu menu = new Menu(ds);
        if(name[0].equals("end"))
            return;
        //String table01 = input.nextLine();
        // String[] table1 = name.split(" ");

        String[] time1 = name[2].split("/");
        int y = Integer.parseInt(time1[0]);
        int m = Integer.parseInt((time1[1]));
        int d = Integer.parseInt(time1[2]);
        LocalDate date1 = LocalDate.of(y, m, d);
        DayOfWeek week1 = date1.getDayOfWeek();
        int week=week1.getValue();
        //String date01 = date1.format(fmt);

        //String week1 = getWeek(date01);
        //int week = Integer.parseInt(week1);
        String[] time2 = name[3].split("/");

        int h = Integer.parseInt(time2[0]);
        int minute = Integer.parseInt(time2[1]);
        int s = Integer.parseInt(time2[2]);
        double discount;
        String r1 = input.nextLine();
        String[] r01 = r1.split(" ");
        ArrayList<Record> records = new ArrayList<>();
        Order order1 = new Order(records);
        int i=1;
        int countDelete=0;
        while(r01[0].compareTo("end")!=0){

            int orderNum = Integer.parseInt(r01[0]);
            if(r01[1].equals("delete")){

                double price1 = 0.5+order1.findRecordByNum(orderNum).getPrice();
                if(price1==0)
                    countDelete++;
                Dish d2=new Dish("delete",-price1);
                Record record2=new Record(orderNum,d2,1,1);
                records.add(record2);
                break;
            }
            Dish d1 = menu.searchDish(r01[1]);
            int portion = Integer.parseInt(r01[2]);
            int num = Integer.parseInt(r01[3]);
            i++;
            //order1.addARecord(orderNum,d1.getName(),portion,num);
            Record record1=new Record(orderNum,d1,portion,num);
            records.add(record1);
            r1= input.nextLine();
            r01 = r1.split(" ");
        }

        while(r01[0].compareTo("end")!=0){

            r1= input.nextLine();
            r01 = r1.split(" ");
            if(r01[0].equals("end"))
                break;

            int orderNum = Integer.parseInt(r01[0]);
            double price1 = order1.findRecordByNum(orderNum).getPrice();
            if(price1==0)
                countDelete++;
            Dish d2=new Dish("delete",-price1);
            Record record2=new Record(orderNum,d2,1,1);
            records.add(record2);
        }
        Order order = new Order(records);
        if (week==6||week==7){
            if(h>9&&h<21||h==9&&minute>=30||h==21&&minute<30||h==21&&minute==30&&s==0)
                discount=1;
            else{

                System.out.println(name[0]+" "+name[1]+": ");
                for(int j=0;j<i-1;j++){
                    if(order.findRecordByNum(j+1).getPrice()!=0)
                        System.out.println(j+1+" "+order.findRecordByNum(j+1).getD().getName()+" "+(int)(0.5+order.findRecordByNum(j+1).getPrice()));
                    else
                        System.out.println(order.findRecordByNum(j+1).getD().getName()+" does not exist");
                }
                for(int j=0;j<countDelete;j++){
                    System.out.println("delete error;");
                }
                System.out.println("table " + name[1] + " out of opening hours");
                return;
            }
        }
        else{
            if(h>=17&&h<20||h==20&&minute<30||h==20&&minute==30&&s==0){
                discount=0.8;
            }
            else if(h>10&&h<14||h==10&&minute>=30||h==14&&minute<30||h==14&&minute==30&&s==0){
                discount=0.6;
            }
            else{

                System.out.println(name[0]+" "+name[1]+": ");
                for(int j=0;j<i-1;j++){
                    if(order.findRecordByNum(j+1).getPrice()!=0)
                        System.out.println(j+1+" "+order.findRecordByNum(j+1).getD().getName()+" "+(int)(0.5+order.findRecordByNum(j+1).getPrice()));
                    else
                        System.out.println(order.findRecordByNum(j+1).getD().getName()+" does not exist");
                }
                for(int j=0;j<countDelete;j++){
                    System.out.println("delete error;");
                }
                System.out.println("table " + name[1] + " out of opening hours");
                return;
            }
        }

        System.out.println(name[0]+" "+name[1]+": ");
        for(int j=0;j<i-1;j++){
            if(order.findRecordByNum(j+1).getPrice()!=0)
                System.out.println(j+1+" "+order.findRecordByNum(j+1).getD().getName()+" "+(int)(0.5+order.findRecordByNum(j+1).getPrice()));
            else
                System.out.println(order.findRecordByNum(j+1).getD().getName()+" does not exist");
        }
        for(int j=0;j<countDelete;j++){
            System.out.println("delete error;");
        }
        System.out.println(name[0]+" "+name[1]+":"+" "+(int)(order.getTotalPrice()*discount+0.5));
    }
}

class Dish{
    private String name;
    private double unit_price;
    Dish(){}
    Dish(String name,double unit_price){
        this.name=name;
        this.unit_price=unit_price;
    }

    public double getPrice(int portion){

        if(portion==2)
            unit_price=unit_price*1.5;
        if(portion==3)
            unit_price = unit_price*2;
        return unit_price;
        //return (int)(unit_price*(1+(0.5*(portion-1))));
    }
    public String getName(){
        return name;
    }
}

class Menu{
    private static ArrayList<Dish> dishs;
    Menu(){}
    public Menu(ArrayList<Dish> dishs){
        this.dishs = dishs;
    }

    public static Dish searchDish(String dishName){
        int i;
        for(i=0;i<dishs.size();i++){
            if(dishs.get(i).getName().compareTo(dishName)==0){
                break;
            }
        }
        if(i== dishs.size()){
            return new Dish(dishName,0);
        }
        return dishs.get(i);
    }
    public Dish addDish(String dishName,double unit_price){
        this.dishs.add(new Dish(dishName,unit_price));
        return new Dish(dishName,unit_price);
    }
}

class Record{

    private int orderNum;
    private Dish d;
    private int portion;
    private int num;
    Record(int orderNum,Dish d,int portion,int num){
        this.orderNum=orderNum;
        this.d=d;
        this.portion=portion;
        this.num=num;
    }
    public int getNum(){
        return num;
    }
    public Dish getD(){
        return d;
    }
    public int getPortion(){
        return portion;
    }
    public int getOrderNum(){
        return orderNum;
    }
    public double getPrice(){
        return d.getPrice(portion)*num;
    }
}

class Order {
    private  ArrayList<Record> records;

    public Order(ArrayList<Record> records) {
        this.records = records;
    }

    public double getTotalPrice() {
        double sum = 0;
        for (Record r : records) {
            sum += (int)(0.5+r.getPrice());
        }
        return sum;
    }

    public Record addARecord(int orderNum, String dishName, int portion, int num) {
        Dish d = Menu.searchDish(dishName);

        this.records.add(new Record(orderNum, d, portion,num));

        return new Record(orderNum, d, portion,num);
    }

    public void delARecordByOrderNum(int orderNum) {
        records.remove(orderNum - 1);
    }

    public Record findRecordByNum(int orderNum) {
        int ordernum=0,portion=0,num=0;
        double price=0;
        String name="";


        for (Record r : this.records) {
            if (r.getOrderNum() == orderNum) {
                ordernum=r.getOrderNum();
                name=r.getD().getName();

                portion=r.getPortion();
                price=r.getD().getPrice(1);
                num=r.getNum();
                break;
            }
        }
        Dish d=new Dish(name,price);
        return new Record(ordernum,d,portion,num);
    }
}

首先要对这道题的时间进行判断,通过LocalDate对日期信息进行处理,再通过DayOfWeek求出该日期为星期几,代码如下:

String[] time1 = name[2].split("/");
int y = Integer.parseInt(time1[0]);
int m = Integer.parseInt((time1[1]));
int d = Integer.parseInt(time1[2]);
LocalDate date1 = LocalDate.of(y, m, d);
DayOfWeek week1 = date1.getDayOfWeek();

然后根据周几和时间计算出折扣,并对点菜信息进行处理:首先判断菜品信息正误,然后有删除和增加订单信息,最后计算总价格。在计算总价格的过程中,我的思路是最后一次性算出所有价格再求和,而订单信息全都储存在Record类里,而Order中的Record属性是以动态数组的形式存在,所以要逐一遍历计算价格求和,代码如下:

public Record findRecordByNum(int orderNum) {
        int ordernum=0,portion=0,num=0;
        double price=0;
        String name="";


        for (Record r : this.records) {
            if (r.getOrderNum() == orderNum) {
                ordernum=r.getOrderNum();
                name=r.getD().getName();

                portion=r.getPortion();
                price=r.getD().getPrice(1);
                num=r.getNum();
                break;
            }
        }
        Dish d=new Dish(name,price);
        return new Record(ordernum,d,portion,num);
    }
public double getTotalPrice() {
        double sum = 0;
        for (Record r : records) {
            sum += (int)(0.5+r.getPrice());
        }
        return sum;
    }

这道题只拿了一半的分,只完成了单桌基本要求,多桌还未实现。

题目集五

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且输入均有效,输出格式如下:
    天数值
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int a = input.nextInt();
        if(a==1){
            int y=input.nextInt();
            int m=input.nextInt();
            int d=input.nextInt();
            Day day = new Day(y,m,d);
            DateUtil date = new DateUtil(d,m,y);
            if(day.validate()){
                int n=input.nextInt();
                date.getNextNDays(n);
                System.out.println(date.showDate());
            }
            else
                System.out.println("Wrong Format");
        }
        else if(a==2){
            int y=input.nextInt();
            int m=input.nextInt();
            int d=input.nextInt();
            Day day = new Day(y,m,d);
            DateUtil date = new DateUtil(d,m,y);
            if(day.validate()){
                int n=input.nextInt();
                date.getPreviousNDays(n);
                System.out.println(date.showDate());
            }
            else
                System.out.println("Wrong Format");
        }
        else if(a==3){
            int y=input.nextInt();
            int m=input.nextInt();
            int d=input.nextInt();
            int y1=input.nextInt();
            int m1=input.nextInt();
            int d1=input.nextInt();
            DateUtil date = new DateUtil(d,m,y);
            DateUtil date1 = new DateUtil(d1,m1,y1);
            if(date.getDay().validate()&&date1.getDay().validate()){
                int n = date.getDaysofDates(date1);
                System.out.println(n);
            }
            else
                System.out.println("Wrong Format");
        }
        else
            System.out.println("Wrong Format");
    }
}
class Year{
    private int value;
    Year(){}
    Year(int value){
        this.value=value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    public boolean isLeapYear(){    //判断是否为闰年
        if(value%4==0&&value%100!=0||value%400==0){
            return true;
        }
        else
            return false;
    }
    public boolean validate(){  //校验数据合法性
        if(value>=1900&&value<=2050)
            return true;
        else
            return false;
    }
    public void yearIncrement(){    //年份增1
        this.value++;
    }
    public void yearReduction(){    //年份减1
        this.value--;
    }
}
class Month{
    private int value;
    private Year year;
    Month(){}
    Month(int yearValue,int monthValue){
        year = new Year(yearValue);
        this.value=monthValue;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    public Year getYear(){
        return year;
    }

    public void setYear(Year year) {
        this.year = year;
    }
    public void resetMin(){ //月份复位(1)
        value=1;
    }
    public void resetMax(){ //月份复位(12)
        value=12;
    }
    public boolean validate(){  //判断月份是否合法
        if(value>=1&&value<=12&& year.validate())
            return true;
        else
            return false;
    }
    public void monthIncrement(){   //月份增1
        this.value++;
        if(value>12){
            resetMin();
            year.yearIncrement();
        }
    }
    public void monthReduction(){   //月份减1
        this.value--;
        if(value==0){
            resetMax();
            year.yearReduction();
        }
    }
}
class Day{
    private int value;
    private Month month;
    private int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
    Day(){}
    Day(int yearValue,int monthValue,int dayValue){
        this.value=dayValue;
        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 value) {
        this.month = value;
    }
    public void resetMin(){//日期复位(1)
        value=1;
    }
    public void resetMax(){// 日期改为当月最大值
        value=mon_maxnum[month.getValue()-1];
    }
    public boolean validate(){//校验数据合法性
        if(month.validate()) {
            if (month.getYear().isLeapYear())
                mon_maxnum[1] = 29;
            else
                mon_maxnum[1] = 28;
            if (value >= 1 && value <= mon_maxnum[month.getValue() - 1] && month.validate())
                return true;
            else
                return false;
        }
        else
            return false;
    }
    public void dayIncrement(){//日期增1
        value++;
        if(month.getYear().isLeapYear())
            mon_maxnum[1]=29;
        else
            mon_maxnum[1]=28;
        if(value>mon_maxnum[month.getValue()-1]){
            resetMin();
            month.monthIncrement();
        }
    }
    public void dayReduction(){//日期减1
        value--;
        if(value==0){
            month.monthReduction();
            if(month.getYear().isLeapYear())
                mon_maxnum[1]=29;
            else
                mon_maxnum[1]=28;
            resetMax();
        }
    }
}
class DateUtil{
    private Day day;
    DateUtil(){}
    DateUtil(int d,int m,int y){
        day = new Day(y,m,d);
    }

    public Day getDay() {
        return day;
    }

    public void setDay(Day day) {
        this.day = day;
    }
    public boolean checkInputValidity(){//校验数据合法性
        if(day.validate())
            return true;
        else
            return false;
    }
    public boolean compareDates(DateUtil date){//比较两个日期的大小
        if(day.getMonth().getYear().getValue()>date.getDay().getMonth().getYear().getValue()){
            return true;
        }
        else if(day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()&&day.getMonth().getValue()>date.getDay().getMonth().getValue()){
            return true;
        }
        else if(day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getValue()>date.getDay().getValue()){
            return true;
        }
        else
            return false;
    }
    public boolean equalTwoDates(DateUtil date){
        if(day.getValue()==date.getDay().getValue()&&day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue())
            return true;
        else
            return false;
    }
    public String showDate(){
        return day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue();
    }
    public DateUtil getNextNDays(int n){
        for(int i=0;i<n;i++){
            day.dayIncrement();
        }
        return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
    }
    public DateUtil getPreviousNDays(int n){
        for(int i=0;i<n;i++){
            day.dayReduction();
        }
        return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
    }
    public int getDaysofDates(DateUtil date){
        int n=0;
        DateUtil date1 = new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
        while(date1.compareDates(date)){
            date.getDay().dayIncrement();
            n++;
        }
        while(date.compareDates(date1)){
            date1.getDay().dayIncrement();
            n++;
        }
        return n;
    }
}

这道题已经设计好了类图,重点就在于理解类之间的关系,以及如何实现类之间的关系。

这道题给的类图耦合性还是比较强的,上一个类作为下一个类的属性,一个类套另一个类,整体上来看并不符合单一职责原则。

我个人认为这道题难度较小,毕竟类图给了,这道题相当于是填空,主要问题就是日期增加的时候没有考虑到日期,月份越界的情况。

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:值
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int a = input.nextInt();
        if(a==1){
            int y=input.nextInt();
            int m=input.nextInt();
            int d=input.nextInt();

            DateUtil date = new DateUtil(y,m,d);
            if(date.checkInputValidity()){
                int n=input.nextInt();
                date.getNextNDays(n);
                System.out.println(y+"-"+m+"-"+d+" next "+n+" days is:"+date.showDate());
            }
            else
                System.out.println("Wrong Format");
        }
        else if(a==2){
            int y=input.nextInt();
            int m=input.nextInt();
            int d=input.nextInt();

            DateUtil date = new DateUtil(y,m,d);
            if(date.checkInputValidity()){
                int n=input.nextInt();
                date.getPreviousNDays(n);
                System.out.println(y+"-"+m+"-"+d+" previous "+n+" days is:"+date.showDate());
            }
            else
                System.out.println("Wrong Format");
        }
        else if(a==3){
            int y=input.nextInt();
            int m=input.nextInt();
            int d=input.nextInt();
            int y1=input.nextInt();
            int m1=input.nextInt();
            int d1=input.nextInt();
            DateUtil date = new DateUtil(y,m,d);
            DateUtil date1 = new DateUtil(y1,m1,d1);
            if(date.checkInputValidity()&&date1.checkInputValidity()){
                int n = date.getDaysofDates(date1);
                System.out.println("The days between "+y+"-"+m+"-"+d+" and "+y1+"-"+m1+"-"+d1+" are:"+n);
            }
            else
                System.out.println("Wrong Format");
        }
        else
            System.out.println("Wrong Format");
    }
}
class Year{
    private int value;
    Year(){}
    Year(int value){
        this.value=value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    public boolean isLeapYear(){
        if(value%4==0&&value%100!=0||value%400==0){
            return true;
        }
        else
            return false;
    }
    public boolean validate(){
        if(value>=1820&&value<=2020)
            return true;
        else
            return false;
    }
    public void yearIncrement(){
        this.value++;
    }
    public void yearReduction(){
        this.value--;
    }
}
class Month{
    private int value;
    Month(){}
    Month(int Value){
        this.value=Value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
    public void resetMin(){
        this.value=1;
    }
    public void resetMax(){
        this.value=12;
    }
    public boolean validate(){
        if(value>=1&&value<=12)
            return true;
        else
            return false;
    }
    public void monthIncrement(){
        this.value++;

    }
    public void monthReduction(){
        this.value--;

    }
}
class Day{
    private int value;
    Day(){}
    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 DateUtil{
    private Year year;
    private Month month;
    private Day day;
    private int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
    DateUtil(){}
    DateUtil(int y,int m,int d){
        year = new Year(y);
        month = new Month(m);
        day = new Day(d);
    }

    public Year getYear() {
        return year;
    }

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

    public Month getMonth() {
        return month;
    }

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

    public Day getDay() {
        return day;
    }

    public void setDay(Day day) {
        this.day = day;
    }
    public void setDayMin(){//设置日期最小值1
        day.setValue(1);
    }
    public void setDayMax(){//设置日期为当月最大值
        day.setValue(mon_maxnum[month.getValue()-1]);
    }
    public boolean checkInputValidity(){//校验输入数据合法性
        if(year.validate()&&month.validate()&&day.getValue()>=1&&day.getValue()<=mon_maxnum[month.getValue()-1])
            return true;
        else
            return false;
    }
    public boolean compareDates(DateUtil date){//判断两个日期的先后
        if(year.getValue()>date.getYear().getValue()){
            return true;
        }
        else if(year.getValue()==date.getYear().getValue()&&month.getValue()>date.getMonth().getValue()){
            return true;
        }
        else if(month.getValue()==date.getMonth().getValue()&&day.getValue()>date.getDay().getValue()){
            return true;
        }
        else
            return false;
    }
    public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等
        if(day.getValue()==date.getDay().getValue()&&month.getValue()==date.getMonth().getValue()&&year.getValue()==date.getYear().getValue())
            return true;
        else
            return false;
    }
    public String showDate(){//日期格式化
        String date = year.getValue()+"-"+month.getValue()+"-"+day.getValue();
        return date;
    }
    public DateUtil getNextNDays(int n){//求下N天
        for(int i=0;i<n;i++){
            day.dayIncrement();
            if(year.isLeapYear()){
                mon_maxnum[1]=29;
            }
            else
                mon_maxnum[1]=28;
            if(day.getValue()>mon_maxnum[month.getValue()-1]){
                day.setValue(1);
                month.monthIncrement();
                if(month.getValue()>12){
                    month.setValue(1);
                    year.yearIncrement();
                }
            }
        }
        return new DateUtil(year.getValue(),month.getValue(),day.getValue());
    }
    public DateUtil getPreviousNDays(int n){//求前N天
        for(int i=0;i<n;i++){
            day.dayReduction();
            if(day.getValue()==0){
                month.monthReduction();
                if(month.getValue()==0){
                    month.setValue(12);
                    year.yearReduction();
                }if(year.isLeapYear()){
                    mon_maxnum[1]=29;
                }
                else
                    mon_maxnum[1]=28;
                day.setValue(mon_maxnum[month.getValue()-1]);
            }
        }
        return new DateUtil(year.getValue(),month.getValue(),day.getValue());
    }
    public int getDaysofDates(DateUtil date){//求两个日期的天数差
        int n=0;
        DateUtil date1 = new DateUtil(year.getValue(),month.getValue(),day.getValue());
        while(date1.compareDates(date)){//每次加一天,直到两个日期相等
            date.getNextNDays(1);
            n++;
        }
        while(date.compareDates(date1)){
            date1.getNextNDays(1);
            n++;
        }
        return n;
    }
}

这道题是上一题的进阶,与上一题相比,弥补了上一题类之间耦合性高的缺点,类Day,Month,Year三个类之间互不干扰,符合单一职责原则。数据的处理统一由DateUtil类处理。

在上一道题的错误经验上,这道题我是一遍过的,依旧是填空,把每个类的方法都填完,程序自然就完成了。

题目集六

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

作者 段喜龙
单位 南昌航空大学

设计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编号]上存款¥[金额]

当前余额为¥[金额]

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

④查询余额业务输出

¥[金额]

金额保留两位小数。

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String str = input.nextLine();
        Data data = new Data();
        while (str.compareTo("#")!=0){
            DealData dealData = new DealData(str,data);
            dealData.getDataResult();
            str = input.nextLine();
        }
    }
}
class UnionPay{
    private String name;
    private Bank[] banks;
    UnionPay(){}
    UnionPay(String name,Bank[] banks){
        this.name=name;
        this.banks=banks;
    }

    public String getName() {
        return name;
    }

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

    public Bank[] getBanks() {
        return banks;
    }

    public void setBanks(Bank[] banks) {
        this.banks = banks;
    }
}
class Bank{
    private String name;
    private User[] users;
    private Account[] accounts;
    private ATM[] atms;
    Bank(){}

    public Bank(String name, User[] users, Account[] accounts, ATM[] atms) {
        this.name = name;
        this.users = users;
        this.accounts = accounts;
        this.atms = atms;
    }

    public String getName() {
        return name;
    }

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

    public User[] getUsers() {
        return users;
    }

    public void setUsers(User[] users) {
        this.users = users;
    }

    public Account[] getAccounts() {
        return accounts;
    }

    public void setAccounts(Account[] accounts) {
        this.accounts = accounts;
    }

    public ATM[] getAtms() {
        return atms;
    }

    public void setAtms(ATM[] atms) {
        this.atms = atms;
    }
}
class User{
    private String name;
    private Account[] accounts;

    public String getName() {
        return name;
    }

    public User() {
    }

    public User(String name, Account[] accounts) {
        this.name = name;
        this.accounts = accounts;
    }

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

    public Account[] getAccounts() {
        return accounts;
    }

    public void setAccounts(Account[] accounts) {
        this.accounts = accounts;
    }
}
class Account{
    private String id;
    private Card[] cards;
    private double balance;
    public Account() {
    }

    public Account(String id, Card[] cards,double balance) {
        this.id = id;
        this.cards = cards;
        this.balance=balance;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Card[] getCards() {
        return cards;
    }

    public void setCards(Card[] cards) {
        this.cards = cards;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}
class Card{
    private String id;
    private String password="88888888";


    public Card() {
    }

    public Card(String id) {
        this.id = id;

    }

    public void setId(String id) {
        this.id = id;
    }

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

    public String getId() {
        return id;
    }

    public String getPassword() {
        return password;
    }


}
class ATM{
    private String id;

    public ATM() {
    }

    public ATM(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}
class Data{
    private UnionPay unionPay;
    Data(){
        Card card1 = new Card("6217000010041315709");
        Card card2 = new Card("6217000010041315715");
        Card card3 = new Card("6217000010041315718");
        Card card4 = new Card("6217000010051320007");
        Card card5 = new Card("6222081502001312389");
        Card card6 = new Card("6222081502001312390");
        Card card7 = new Card("6222081502001312399");
        Card card8 = new Card("6222081502001312400");
        Card card9 = new Card("6222081502051320785");
        Card card10 = new Card("6222081502051320786");
        Card[] cards1 = {card1,card2};
        Card[] cards2 = {card3};
        Card[] cards3 = {card4};
        Card[] cards4 = {card5};
        Card[] cards5 = {card6};
        Card[] cards6 = {card7,card8};
        Card[] cards7 = {card9};
        Card[] cards8 = {card10};
        Account account1 = new Account("3217000010041315709",cards1,10000.00);
        Account account2= new Account("3217000010041315715",cards2,10000.00);
        Account account3 = new Account("3217000010051320007",cards3,10000.00);
        Account account4 = new Account("3222081502001312389",cards4,10000.00);
        Account account5 = new Account("3222081502001312390",cards5,10000.00);
        Account account6 = new Account("3222081502001312399",cards6,10000.00);
        Account account7 = new Account("3222081502051320785",cards7,10000.00);
        Account account8 = new Account("3222081502051320786",cards8,10000.00);
        Account[] accounts1 = {account1,account2};
        Account[] accounts2 = {account3};
        Account[] accounts3 = {account4,account5,account6};
        Account[] accounts4 = {account7,account8};
        User user1 = new User("杨过",accounts1);
        User user2 = new User("郭靖",accounts2);
        User user3 = new User("张无忌",accounts3);
        User user4 = new User("韦小宝",accounts4);
        User[] users1 = {user1,user2};
        User[] users2 = {user3,user4};
        Account[] accounts01={account1,account2,account3};
        Account[] accounts02={account4,account5,account6,account7,account8};
        ATM atm1 = new ATM("01");
        ATM atm2 = new ATM("02");
        ATM atm3 = new ATM("03");
        ATM atm4 = new ATM("04");
        ATM atm5 = new ATM("05");
        ATM atm6 = new ATM("06");
        ATM[] atms1 = {atm1,atm2,atm3,atm4};
        ATM[] atms2 = {atm5,atm6};
        Bank bank1 = new Bank("中国建设银行",users1,accounts01,atms1);
        Bank bank2 = new Bank("中国工商银行",users2,accounts02,atms2);
        Bank[] banks = {bank1,bank2};
        unionPay = new UnionPay("中国银联",banks);
    }

    public UnionPay getUnionPay() {
        return unionPay;
    }

    public void setUnionPay(UnionPay unionPay) {
        this.unionPay = unionPay;
    }
    public void setBalance(String cardId,double money){
        searchAccount(cardId).setBalance(searchAccount(cardId).getBalance()+money);
    }
    public Account searchAccount(String s){
        Bank[] banks=unionPay.getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return accounts[j];
                }
            }
        }
        return null;
    }

}
class DealData{
    private String s;
    private Data data;
    DealData(){}
    DealData(String s,Data data){
        this.s=s;
        this.data=data;
    }
    public void getDataResult(){
        String[] s01 = s.split(" ");
        String[] s1 = new String[4];
        int k=0;
        for(int i=0;i<s01.length;i++){
            if(s01[i].compareTo("")!=0){
                s1[k]=s01[i];
                k++;
            }
        }
        if(s01.length==1){
            if(rightCard(s1[0])){
                System.out.printf("¥%.2f\n",searchAccount(s1[0]).getBalance());
            }
        }
        else {
            if(rightCard(s1[0])){
                if(rightPassword(s1[1])){
                    if(rightATM(s1[2])){
                        if(isLowBalance(s1[0],s1[3])){
                            if(isSameBank(s1[0],s1[2])){
                                String user_name = searchUser(s1[0]).getName();
                                String bank_name = searchBank(s1[0]).getName();
                                double money = Double.parseDouble(s1[3]);
                                if(isTakeMoney(s1[3])) {
                                    System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n",money);
                                    money=-money;
                                }
                                else {
                                    money=-money;
                                    System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n",money);
                                }
                                setBalance(s1[0],money);
                                System.out.printf("当前余额为¥%.2f\n",searchAccount(s1[0]).getBalance());
                            }
                        }
                    }
                }
            }
        }
    }
    public void setBalance(String cardId,double money){
        data.setBalance(cardId,money);
    }
    public boolean isTakeMoney(String s){
        double money = Double.parseDouble(s);
        if(money>0)
            return true;
        else
            return false;
    }
    public Bank searchBank(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return banks[i];
                }
            }
        }
        return null;
    }
    public User searchUser(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            User[] users=banks[i].getUsers();
            for(int j=0;j<users.length;j++){
                Account[] accounts=users[j].getAccounts();
                for(int k=0;k<accounts.length;k++){
                    Card[] cards = accounts[k].getCards();
                    for(int q=0;q<cards.length;q++){
                        if(cards[q].getId().equals(s))
                            return users[j];
                    }
                }
            }
        }
        return null;
    }
    public Account searchAccount(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return accounts[j];
                }
            }
        }
        return null;
    }
    public Card searchCard(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return cards[k];
                }
            }
        }
        return null;
    }
    public boolean isLowBalance(String s1,String s){

        double money = Double.parseDouble(s);
        if(money<=searchAccount(s1).getBalance())
            return true;
        else {
            System.out.println("Sorry,your account balance is insufficient.");
            return false;
        }
    }
    public boolean isSameBank(String s1,String s2){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            ATM[] atms=banks[i].getAtms();
            for(int j=0;j<atms.length;j++){
                if(atms[j].getId().equals(s2)){
                    Account[] accounts=banks[i].getAccounts();
                    for(int j1=0;j1<accounts.length;j1++){
                        Card[] cards=accounts[j1].getCards();
                        for(int k=0;k<cards.length;k++){
                            if(cards[k].getId().equals(s1))
                                return true;
                        }
                    }
                }

            }

        }
        System.out.println("Sorry,cross-bank withdrawal is not supported.");
        return false;
    }
    public boolean rightCard(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return true;
                }
            }
        }
        System.out.println("Sorry,this card does not exist.");
        return false;
    }
    public boolean rightPassword(String s){
        if(s.compareTo("88888888")==0)
            return true;
        else{
            System.out.println("Sorry,your password is wrong.");
                return false;
        }
    }
    public boolean rightATM(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            ATM[] atms=banks[i].getAtms();
            for(int j=0;j<atms.length;j++){
                if(atms[j].getId().equals(s))
                    return true;
            }
        }
        System.out.println("Sorry,the ATM's id is wrong.");
        return false;
    }
}

这道题没有给类图,因此在做这道题的时候花费了较多的时间。类的设计我主要是根据作业说明里的信息来做的,我个人其实并不满意自己设计的类,因为耦合性太高了,通过这次设计类,我感受到了自己在设计这方面的不足,这道题里,类之间的多对一关系较难处理。

我这道题其实主要是在DealData类里完成的,DealData类相当于控制类,Data类用来存储原始数据,主要思想就是遍历数组,直到搜索到目标字符串,然后返回需要的信息,代码如下:

public Card searchCard(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return cards[k];
                }
            }
        }
        return null;
    }

实现业务功能的主要代码如下:

public void getDataResult(){
        String[] s01 = s.split(" ");
        String[] s1 = new String[4];
        int k=0;
        for(int i=0;i<s01.length;i++){
            if(s01[i].compareTo("")!=0){
                s1[k]=s01[i];
                k++;
            }
        }
        if(s01.length==1){
            if(rightCard(s1[0])){
                System.out.printf("¥%.2f\n",searchAccount(s1[0]).getBalance());
            }
        }
        else {
            if(rightCard(s1[0])){
                if(rightPassword(s1[1])){
                    if(rightATM(s1[2])){
                        if(isLowBalance(s1[0],s1[3])){
                            if(isSameBank(s1[0],s1[2])){
                                String user_name = searchUser(s1[0]).getName();
                                String bank_name = searchBank(s1[0]).getName();
                                double money = Double.parseDouble(s1[3]);
                                if(isTakeMoney(s1[3])) {
                                    System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n",money);
                                    money=-money;
                                }
                                else {
                                    money=-money;
                                    System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n",money);
                                }
                                setBalance(s1[0],money);
                                System.out.printf("当前余额为¥%.2f\n",searchAccount(s1[0]).getBalance());
                            }
                        }
                    }
                }
            }
        }
    }

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

作者 段喜龙
单位 南昌航空大学

设计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编号]上取款¥[金额]

当前余额为¥[金额]

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

③查询余额业务输出

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

金额保留两位小数。

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String str = input.nextLine();
        Data data = new Data();
        while (str.compareTo("#")!=0){
            DealData dealData = new DealData(str,data);
            dealData.getDataResult();
            str = input.nextLine();
        }
    }
}
class UnionPay{
    private String name;
    private Bank[] banks;
    UnionPay(){}
    UnionPay(String name,Bank[] banks){
        this.name=name;
        this.banks=banks;
    }

    public Bank[] getBanks() {
        return banks;
    }


}
class Bank{
    private String name;
    private User[] users;
    private Account[] accounts;
    private ATM[] atms;
    Bank(){}

    public Bank(String name, User[] users, Account[] accounts, ATM[] atms) {
        this.name = name;
        this.users = users;
        this.accounts = accounts;
        this.atms = atms;
    }

    public String getName() {
        return name;
    }

    public User[] getUsers() {
        return users;
    }



    public Account[] getAccounts() {
        return accounts;
    }



    public ATM[] getAtms() {
        return atms;
    }


}
class User{
    private String name;
    private Account[] accounts;

    public String getName() {
        return name;
    }

    public User() {
    }

    public User(String name, Account[] accounts) {
        this.name = name;
        this.accounts = accounts;
    }

    public Account[] getAccounts() {
        return accounts;
    }


}
class Account{
    private String id;
    private Card[] cards;
    private double balance;
    private boolean kind;//true为借记,false为贷记
    public Account() {
    }

    public Account(String id, Card[] cards,double balance) {
        this.id = id;
        this.cards = cards;
        this.balance=balance;
        this.kind=true;
    }

    public boolean isKind() {
        return kind;
    }

    public void setKind(boolean kind) {
        this.kind = kind;
    }

    public Card[] getCards() {
        return cards;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}
class Card{
    private String id;
    private String password="88888888";


    public Card() {
    }

    public Card(String id) {
        this.id = id;

    }
    public String getId() {
        return id;
    }

}
class ATM{
    private String id;

    public ATM() {
    }

    public ATM(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}
class Data{
    private UnionPay unionPay;
    Data(){
        Card card1 = new Card("6217000010041315709");
        Card card2 = new Card("6217000010041315715");
        Card card3 = new Card("6217000010041315718");
        Card card4 = new Card("6217000010051320007");
        Card card5 = new Card("6222081502001312389");
        Card card6 = new Card("6222081502001312390");
        Card card7 = new Card("6222081502001312399");
        Card card8 = new Card("6222081502001312400");
        Card card9 = new Card("6222081502051320785");
        Card card10 = new Card("6222081502051320786");
        Card card11 = new Card("6640000010045442002");
        Card card12 = new Card("6640000010045442003");
        Card card13 = new Card("6640000010045441009");
        Card card14 = new Card("6630000010033431001");
        Card card15 = new Card("6630000010033431008");
        Card[] cards1 = {card1,card2};
        Card[] cards2 = {card3};
        Card[] cards3 = {card4};
        Card[] cards4 = {card5};
        Card[] cards5 = {card6};
        Card[] cards6 = {card7,card8};
        Card[] cards7 = {card9};
        Card[] cards8 = {card10};
        Card[] cards9 = {card11,card12};
        Card[] cards10 = {card13};
        Card[] cards11 = {card14};
        Card[] cards12 = {card15};
        Account account1 = new Account("3217000010041315709",cards1,10000.00);
        Account account2= new Account("3217000010041315715",cards2,10000.00);
        Account account3 = new Account("3217000010051320007",cards3,10000.00);
        Account account4 = new Account("3222081502001312389",cards4,10000.00);
        Account account5 = new Account("3222081502001312390",cards5,10000.00);
        Account account6 = new Account("3222081502001312399",cards6,10000.00);
        Account account7 = new Account("3222081502051320785",cards7,10000.00);
        Account account8 = new Account("3222081502051320786",cards8,10000.00);
        Account account9 = new Account("3640000010045442002",cards9,10000.00);
        Account account10 = new Account("3640000010045441009",cards10,10000.00);
        Account account11 = new Account("3630000010033431001",cards11,10000.00);
        Account account12 = new Account("3630000010033431008",cards12,10000.00);
        account9.setKind(false);
        account10.setKind(false);
        account11.setKind(false);
        account12.setKind(false);
        Account[] accounts1 = {account1,account2};
        Account[] accounts2 = {account3};
        Account[] accounts3 = {account4,account5,account6};
        Account[] accounts4 = {account7,account8};
        Account[] accounts5 = {account9};
        Account[] accounts6 = {account10};
        Account[] accounts7 = {account11};
        Account[] accounts8 = {account12};
        User user1 = new User("杨过",accounts1);
        User user2 = new User("郭靖",accounts2);
        User user3 = new User("张无忌",accounts3);
        User user4 = new User("韦小宝",accounts4);
        User user5 = new User("张三丰",accounts5);
        User user6 = new User("令狐冲",accounts6);
        User user7 = new User("乔峰",accounts7);
        User user8 = new User("洪七公",accounts8);
        User[] users1 = {user1,user2,user5};
        User[] users2 = {user3,user4,user6};
        User[] users3 = {user7,user8};
        Account[] accounts01={account1,account2,account3,account9};
        Account[] accounts02={account4,account5,account6,account7,account8,account10};
        Account[] accounts03={account11,account12};
        ATM atm1 = new ATM("01");
        ATM atm2 = new ATM("02");
        ATM atm3 = new ATM("03");
        ATM atm4 = new ATM("04");
        ATM atm5 = new ATM("05");
        ATM atm6 = new ATM("06");
        ATM atm7 = new ATM("07");
        ATM atm8 = new ATM("08");
        ATM atm9 = new ATM("09");
        ATM atm10 = new ATM("10");
        ATM atm11 = new ATM("11");
        ATM[] atms1 = {atm1,atm2,atm3,atm4};
        ATM[] atms2 = {atm5,atm6};
        ATM[] atms3 = {atm7,atm8,atm9,atm10,atm11};
        Bank bank1 = new Bank("中国建设银行",users1,accounts01,atms1);
        Bank bank2 = new Bank("中国工商银行",users2,accounts02,atms2);
        Bank bank3 = new Bank("中国农业银行",users3,accounts03,atms3);
        Bank[] banks = {bank1,bank2,bank3};
        unionPay = new UnionPay("中国银联",banks);
    }

    public UnionPay getUnionPay() {
        return unionPay;
    }

    public void setBalance(String cardId,double money){
        searchAccount(cardId).setBalance(searchAccount(cardId).getBalance()+money);
    }
    public Account searchAccount(String s){
        Bank[] banks=unionPay.getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return accounts[j];
                }
            }
        }
        return null;
    }

}
class DealData{
    private String s;
    private Data data;
    DealData(){}
    DealData(String s,Data data){
        this.s=s;
        this.data=data;
    }
    public void getDataResult(){
        String[] s01 = s.split(" ");
        String[] s1 = new String[4];
        int k=0;
        for(int i=0;i<s01.length;i++){
            if(s01[i].compareTo("")!=0){
                s1[k]=s01[i];
                k++;
            }
        }
        if(s01.length==1){
            if(rightCard(s1[0])){
                System.out.printf("业务:查询余额 ¥%.2f\n",searchAccount(s1[0]).getBalance());
            }
        }
        else {
            if(rightCard(s1[0])){
                if(rightPassword(s1[1])){
                    if(rightATM(s1[2])){
                        if(searchAccount(s1[0]).isKind()){
                            if(isLowBalance(s1[0],s1[3],s1[2])) {
                                if (isSameBank(s1[0], s1[2])) {
                                    String user_name = searchUser(s1[0]).getName();
                                    String bank_name = searchBank(s1[2]).getName();
                                    double money = Double.parseDouble(s1[3]);
                                    if (isTakeMoney(s1[3])) {
                                        System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
                                        money = -money;
                                    } else {
                                        money = -money;
                                        System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
                                    }
                                    setBalance(s1[0], money);
                                    System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
                                } else {
                                    String user_name = searchUser(s1[0]).getName();
                                    String bank_name = searchBank(s1[2]).getName();
                                    double money = Double.parseDouble(s1[3]);
                                    double money1 = 0;
                                    if (isTakeMoney(s1[3])) {
                                        //手续费
                                        money1=crossBankMoney(s1[2],s1[3]);
                                        System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
                                        money = money1 + money;
                                        money = -money;
                                    } else {
                                        money = -money;
                                        System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
                                    }
                                    setBalance(s1[0], money);
                                    System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
                                }
                            }
                            else{
                                System.out.println("Sorry,your account balance is insufficient.");
                            }
                        }
                        else{
                            if(isLowBalance(s1[0],s1[3],s1[2])) {
                                if (isSameBank(s1[0], s1[2])) {
                                    String user_name = searchUser(s1[0]).getName();
                                    String bank_name = searchBank(s1[2]).getName();
                                    double money = Double.parseDouble(s1[3]);
                                    if (isTakeMoney(s1[3])) {
                                        System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
                                        money = -money;
                                    } else {
                                        money = -money;
                                        System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
                                    }
                                    setBalance(s1[0], money);
                                    System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
                                } else {

                                    String user_name = searchUser(s1[0]).getName();
                                    String bank_name = searchBank(s1[2]).getName();
                                    double money = Double.parseDouble(s1[3]);
                                    double money1 = 0;
                                    if (isTakeMoney(s1[3])) {
                                        //手续费
                                        money1=crossBankMoney(s1[2],s1[3]);
                                        System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
                                        money = money1 + money;
                                        money = -money;
                                    } else {
                                        money = -money;
                                        System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
                                    }
                                    setBalance(s1[0], money);
                                    System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
                                }
                            }else{
                                String user_name = searchUser(s1[0]).getName();
                                String bank_name = searchBank(s1[2]).getName();
                                double money = Double.parseDouble(s1[3]);
                                double t=money;
                                double money0 = 0;//透支手续费
                                if(searchAccount(s1[0]).getBalance()>0)
                                    money0=(money-searchAccount(s1[0]).getBalance())*0.05;
                                else{
                                    money0=(money)*0.05;
                                }
                                if (isSameBank(s1[0], s1[2])) {
                                    if (isTakeMoney(s1[3])) {
                                        money+=money0;
                                        money = -money;
                                        setBalance(s1[0], money);
                                        if(searchAccount(s1[0]).getBalance()<=-50000){
                                            System.out.println("Sorry,your account balance is insufficient.");
                                        }else
                                            System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", t);
                                    } else {
                                        money = -money;
                                        System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
                                        setBalance(s1[0], money);
                                    }
                                } else {
                                    double money1 = 0;
                                    if (isTakeMoney(s1[3])) {
                                        //手续费
                                        money1=crossBankMoney(s1[2],s1[3]);
                                        money = money1 + money;
                                        money+=money0;
                                        money = -money;
                                        setBalance(s1[0], money);
                                        if(searchAccount(s1[0]).getBalance()<=-50000){
                                            System.out.println("Sorry,your account balance is insufficient.");
                                        }else
                                            System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", t);
                                    } else {
                                        money = -money;
                                        System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
                                        setBalance(s1[0], money);
                                    }
                                }
                                if(searchAccount(s1[0]).getBalance()>-50000)
                                    System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
                            }
                        }
                    }
                }
            }
        }
    }
    public double crossBankMoney(String s,String s1){//s ATM,s1 money
        double money1=0;
        double money = Double.parseDouble(s1);
        if (searchBank(s).getName().equals("中国建设银行")) {
            money1 = money * 0.02;
        }
        if (searchBank(s).getName().equals("中国工商银行")) {
            money1 = money * 0.03;
        }
        if (searchBank(s).getName().equals("中国农业银行")) {
            money1 = money * 0.04;
        }
        return money1;
    }
    public void setBalance(String cardId,double money){
        data.setBalance(cardId,money);
    }
    public boolean isTakeMoney(String s){
        double money = Double.parseDouble(s);
        if(money>0)
            return true;
        else
            return false;
    }
    public Bank searchBank(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            ATM[] atms=banks[i].getAtms();
            for(int j=0;j<atms.length;j++){
                if(atms[j].getId().equals(s))
                    return banks[i];

            }
        }
        return null;
    }
    public User searchUser(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            User[] users=banks[i].getUsers();
            for(int j=0;j<users.length;j++){
                Account[] accounts=users[j].getAccounts();
                for(int k=0;k<accounts.length;k++){
                    Card[] cards = accounts[k].getCards();
                    for(int q=0;q<cards.length;q++){
                        if(cards[q].getId().equals(s))
                            return users[j];
                    }
                }
            }
        }
        return null;
    }
    public Account searchAccount(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return accounts[j];
                }
            }
        }
        return null;
    }
    public boolean isLowBalance(String s1,String s,String s2){
        double money = Double.parseDouble(s);
        if(isSameBank(s1,s2)){
            if(money<=searchAccount(s1).getBalance())
                return true;
            else {
                return false;
            }
        }else{
            if(money+crossBankMoney(s2,s)<=searchAccount(s1).getBalance())
                return true;
            else {
                return false;
            }
        }


    }
    public boolean isSameBank(String s1,String s2){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            ATM[] atms=banks[i].getAtms();
            for(int j=0;j<atms.length;j++){
                if(atms[j].getId().equals(s2)){
                    Account[] accounts=banks[i].getAccounts();
                    for(int j1=0;j1<accounts.length;j1++){
                        Card[] cards=accounts[j1].getCards();
                        for(int k=0;k<cards.length;k++){
                            if(cards[k].getId().equals(s1))
                                return true;
                        }
                    }
                }

            }

        }
        return false;
    }
    public boolean rightCard(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            Account[] accounts=banks[i].getAccounts();
            for(int j=0;j<accounts.length;j++){
                Card[] cards=accounts[j].getCards();
                for(int k=0;k<cards.length;k++){
                    if(cards[k].getId().equals(s))
                        return true;
                }
            }
        }
        System.out.println("Sorry,this card does not exist.");
        return false;
    }
    public boolean rightPassword(String s){
        if(s.compareTo("88888888")==0)
            return true;
        else{
            System.out.println("Sorry,your password is wrong.");
            return false;
        }
    }
    public boolean rightATM(String s){
        Bank[] banks=data.getUnionPay().getBanks();
        for(int i=0;i<banks.length;i++){
            ATM[] atms=banks[i].getAtms();
            for(int j=0;j<atms.length;j++){
                if(atms[j].getId().equals(s))
                    return true;
            }
        }
        System.out.println("Sorry,the ATM's id is wrong.");
        return false;
    }
}

这题与上一题相比主要多了两个内容,一个是可以跨行处理业务,一个是银行账户分借记账户和贷记账户。

处理以上两个新增内容,我主要是通过增加判断来完成,比如判断银行账户的种类:

private boolean kind;//true为借记,false为贷记
public boolean isKind() {
        return kind;
    }

判断是否跨行,如果是,判断在哪个银行,这个银行的手续费是多少,代码如下:

public double crossBankMoney(String s,String s1){//s ATM,s1 money
        double money1=0;
        double money = Double.parseDouble(s1);
        if (searchBank(s).getName().equals("中国建设银行")) {
            money1 = money * 0.02;
        }
        if (searchBank(s).getName().equals("中国工商银行")) {
            money1 = money * 0.03;
        }
        if (searchBank(s).getName().equals("中国农业银行")) {
            money1 = money * 0.04;
        }
        return money1;
    }

然后还有个主要问题就是判断余额是否大于取款,如果跨行,还要考虑到手续费,代码如下:

public boolean isLowBalance(String s1,String s,String s2){
        double money = Double.parseDouble(s);
        if(isSameBank(s1,s2)){
            if(money<=searchAccount(s1).getBalance())
                return true;
            else {
                return false;
            }
        }else{
            if(money+crossBankMoney(s2,s)<=searchAccount(s1).getBalance())
                return true;
            else {
                return false;
            }
        }
    }

踩坑心得

  1. 题目集四7-1中,通过一个含有年月日的具体日期来判断该日期为星期几,可以使用time包下的LocalDate和DayOfWeek;
  2. 题目集六7-4中,由于类与类之间大多是多对一之间的关系,而且都是以数组为属性,所以在搜索某一确定的实例化对象时需要遍历所有在它的上层数组,设计类的时候把所有的处理方法都放在DealData一个类中,非常不方便,应该在每个类里创造一个搜索方法,在DealData中只要逐一调用;
  3. 在题目集六中,方法设计时犯了低级错误,在形参命名时并没有使用英文全称,偷懒使用s字母,导致在后续调用方法时忘记了形参是什么,结果又要返回去看代码,浪费了很多时间,这也是给自己埋雷,长个教训。如:public Account searchAccount(String s);
  4. 要多留心空格,有个测试点格式错误,找空格找了一个小时,结果是在人名后面多了个空格;另外在String类中经常要对空格进行删除,常见的有replace(" ","")删除所有空格trim()//删除首尾空格
  5. pta测试点经常出现非零返回,一般来说都是数组越界,回顾代码,推测是slipt返回的新数组与设想的数组长度不同,我的解决方案是加入判断,如果所返回的数组长度与预设长度不一致,则跳过;

改进建议

  1. 规范命名,不要嫌弃名字过长,易懂最重要;
  2. 设计类时,每个类应该要有一些基本处理信息的方法,不要把所有的步骤都堆积到一个类里,如题目集六7-4中的DealData类;
  3. 设计类时,要时刻记得七大设计原则——SRP,迪米特法则,OCP,合成复用原则,LSP,接口隔离原则,依赖倒转原则;

总结

上一次总结偏向于语法的学习,这一次重点更偏向于设计,设计时不光要考虑到每个类本身,还要考虑到各个类之间的关系。

这三次题目集收获颇多,对语法的掌握有了更深的理解,通过题目集六对类的设计也有了新的认识,对类的七大设计原则也有了切身的体会;但在类的设计过程中,明显感觉到自己对于这方面比较生疏,最后生成的类图也反应出虽然拿了满分,但类之间的关系还存在很大的改进空间。

设计对我而言学习之路还很长,老师最近还在给我们讲23种设计模式,这些设计模式能明显的反映出七大设计原则,使我们对类的设计有更好的理解。

posted @ 2023-04-30 00:06  B饭老司机  阅读(31)  评论(0编辑  收藏  举报