OOP第三阶段作业总结

发布时间 2023-06-27 21:17:38作者: Vousêtesunique

一、前言

在第三阶段作业中,五次训练集得分依次为100、100、100、100、96. 五次训练集都不简单。
其中,训练集09虽然题量较少,但程序比较复杂,而且老师也对代码的编写有要求,比如代码行数小于60为一档、小于100为二挡、小于150为三挡,而且代码必须模块化。
训练集07、08、10、11题量都较大,都有一道较大的程序题,不过在经历之前的训练后,完成这类型的大程序已经不在话下训练集07、08、10都全完成,训练集11只有一个测试点没通过,找了很久也没找出问题所在。

二、设计与分析

OOP训练集07 7-1 菜单计价程序-5
类图如下:

设计分析与心得
由于上次OOP训练集06 7-1 菜单计价程序-4仅仅得了67分,为了培养坚韧不拔的品质,一定要将此题拿下。
通读题目描述后,与上次的区别就是少了很多异常情况,增加了口味度情况,以及增加了客户信息。总体来说比上次简单。
Dish类用于储存单个菜品信息:菜品名称、单价,并能根据单价和份额计算该菜品价格;
Menu类:对应菜谱,包含饭店提供的所有菜的信息。根据菜名在菜谱中查找菜品信息,返回Dish对象,以及添加菜品信息;
Record类:保存订单上的一道菜品记录:序号和菜品份额、份数以及口味度值。并能计算该条记录的价格;
Order类:保存用户点的所有菜的信息:订单上每一道的记录。有添加菜品的功能、能根据序号删除一条菜品记录、能根据序号查找一条菜品记录;
Table类:储存一桌的信息:桌号、日期、订单、客户信息、口味度总和。能计算该桌的价格;
Tables类:保存每桌的信息。能添加桌子信息,按用户名称寻找桌子,根据用户名称计算该用户需付款,并能打印各桌信息;
Customer类:储存一个用户的信息:用户名称、用户电话号码。
Customers类:储存所有用户信息。能根据用户名称查找该用户信息,将用户根据名称排序后打印用户信息。
源码如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Menu menu = new Menu();
        Tables tables = new Tables();
        Customers customers = new Customers();
        int tableCount = 0;
        boolean isTableError = false;
        while (true) {
            String str = sc.nextLine();
            if (str.equals("end")) {
                break;
            }
            String[] splitStr = str.split(" ");
            if (str.matches("[\\u4e00-\\u9fa5]+\\s[0-9]+")) { // 菜谱中普通菜
                if (tableCount == 0) {
                    int unit_price = Integer.parseInt(splitStr[1]);
                    Dish preDish = menu.searthDish(splitStr[0]);
                    if (preDish == null) {
                        menu.addDish(splitStr[0], null, unit_price, false);
                    } else { // 相同菜品情况
                        preDish.unit_price = unit_price;
                        preDish.isSpecialty = false;
                    }
                } else {
                    tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                }
            } else if (str.matches("[\\u4e00-\\u9fa5]+\\s[\\u4e00-\\u9fa5]{2}\\s[0-9]+\\sT")) { // 菜谱中特色菜
                if (tableCount == 0) {
                    int unit_price = Integer.parseInt(splitStr[2]);
                    Dish preDish = menu.searthDish(splitStr[0]);
                    if (preDish == null) {
                        menu.addDish(splitStr[0], splitStr[1], unit_price, true);
                    } else {
                        preDish.flavor = splitStr[1];
                        preDish.unit_price = unit_price;
                        preDish.isSpecialty = true;
                    }
                } else {
                    tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                }
            } else if (splitStr[0].equals("table")) {
                if (str.matches(
                        "table\\s[0-9]\\s:\\s[a-z]{1,10}\\s(180|181|189|133|135|136)[0-9]{8}\\s[0-9]{1,4}/[0-9]{1,2}/[0-9]{1,2}\\s\\d{1,2}/\\d{1,2}/\\d{1,2}")
                        && checkTimeValidity(splitStr[5], splitStr[6])) { // 桌号标识
                    int tableNum = Integer.parseInt(splitStr[1]);
                    String[] times = splitStr[6].split("/");
                    int hour = Integer.parseInt(times[0]);
                    int minute = Integer.parseInt(times[1]);
                    int second = Integer.parseInt(times[2]);
                    int dayOfWeek = getDayOfWeek(splitStr[5]);
                    if (isDuringTime(dayOfWeek, hour, minute, second)) {
                        isTableError = false;
                        String[] dates = splitStr[5].split("/");
                        int year = Integer.parseInt(dates[0]);
                        int month = Integer.parseInt(dates[1]);
                        int day = Integer.parseInt(dates[2]);
                        tables.addTable(tableNum, year, month, day, hour, minute, second, dayOfWeek, splitStr[3]);
                        tableCount++;
                        StringBuilder sb = new StringBuilder();
                        sb.append("table ").append(tableNum).append(": ");
                        tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                        Customer preCustomer = customers.findCustomerByName(splitStr[3]);
                        if (preCustomer == null) { // customer
                            customers.addCustomer(splitStr[3], splitStr[4]);
                        }
                    } else {
                        isTableError = true;
                        StringBuilder sb = new StringBuilder();
                        sb.append("table ").append(tableNum).append(" out of opening hours");
                        if (tableCount == 0) {
                            System.out.println(sb.toString());
                        } else {
                            tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                        }
                    }
                } else {
                    isTableError = true;
                    if (tableCount == 0) {
                        System.out.println("wrong format");
                    } else {
                        tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                    }
                }
            } else if (tableCount > 0 && str.matches("\\d+\\s[\\u4e00-\\u9fa5]+\\s\\d\\s\\d+")) { // 点普通菜
                Dish dish = menu.searthDish(splitStr[1]);
                if (dish == null) { // 菜谱中没有
                    StringBuilder sb = new StringBuilder();
                    sb.append(splitStr[1]).append(" does not exist");
                    tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                } else {
                    if (dish.flavor == null) {
                        int orderNum = Integer.parseInt(splitStr[0]);
                        int portion = Integer.parseInt(splitStr[2]);
                        int num = Integer.parseInt(splitStr[3]);
                        Record newRecord = tables.findTableByIndex(tableCount - 1).order.addARecord(orderNum, dish, -1,
                                portion, num);
                        StringBuilder sb = new StringBuilder();
                        sb.append(orderNum).append(" ").append(splitStr[1]).append(" ")
                                .append(newRecord.getPrice());
                        tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                    } else {
                        tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                    }
                }
            } else if (tableCount > 0 && str.matches("\\d+\\s[\\u4e00-\\u9fa5]+\\s\\d+\\s\\d\\s\\d+")) {// 点特色菜
                Dish dish = menu.searthDish(splitStr[1]);
                if (dish == null) { // 菜谱中没有
                    StringBuilder sb = new StringBuilder();
                    sb.append(splitStr[1]).append(" does not exist");
                    tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                } else {
                    if (dish.flavor != null) {
                        int taste = Integer.parseInt(splitStr[2]);
                        int orderNum = Integer.parseInt(splitStr[0]);
                        int portion = Integer.parseInt(splitStr[3]);
                        int num = Integer.parseInt(splitStr[4]);
                        if (dish.flavor.equals("川菜")) {
                            if (taste < 0 || taste > 5) {
                                StringBuilder sb = new StringBuilder();
                                sb.append("spicy num out of range :").append(taste);
                                tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                                continue;
                            } else {
                                tables.findTableByIndex(tableCount - 1).chuanFlavor += taste * num;
                                tables.findTableByIndex(tableCount - 1).chuanCount += num;
                            }
                        }
                        if (dish.flavor.equals("晋菜")) {
                            if (taste < 0 || taste > 4) {
                                StringBuilder sb = new StringBuilder();
                                sb.append("acidity num out of range :").append(taste);
                                tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                                continue;
                            } else {
                                tables.findTableByIndex(tableCount - 1).jinFlavor += taste * num;
                                tables.findTableByIndex(tableCount - 1).jinCount += num;
                            }
                        }
                        if (dish.flavor.equals("浙菜")) {
                            if (taste < 0 || taste > 3) {
                                StringBuilder sb = new StringBuilder();
                                sb.append("sweetness num out of range :").append(taste);
                                tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                                continue;
                            } else {
                                tables.findTableByIndex(tableCount - 1).zheFlavor += taste * num;
                                tables.findTableByIndex(tableCount - 1).zheCount += num;
                            }
                        }
                        if (portion < 1 || portion > 3) {
                            tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                            continue;
                        }
                        Record newRecord = tables.findTableByIndex(tableCount - 1).order.addARecord(orderNum, dish,
                                taste, portion, num);
                        StringBuilder sb = new StringBuilder();
                        sb.append(orderNum).append(" ").append(splitStr[1]).append(" ")
                                .append(newRecord.getPrice());
                        tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                    } else {
                        tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                    }
                }
            } else if (tableCount > 0 && str.matches("\\d+\\sdelete")) { // delete
                int orderNum = Integer.parseInt(splitStr[0]);
                Record delRecord = tables.findTableByIndex(tableCount - 1).order.findRecordByNum(orderNum);
                if (delRecord != null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(delRecord.orderNum).append(" ").append(delRecord.dish.name).append(" ")
                            .append(delRecord.getPrice());
                    if (delRecord.dish.isSpecialty == true) {
                        if (delRecord.dish.flavor.equals("川菜")) {
                            tables.findTableByIndex(tableCount - 1).chuanFlavor -= delRecord.taste * delRecord.num;
                            tables.findTableByIndex(tableCount - 1).chuanCount -= delRecord.num;
                        } else if (delRecord.dish.flavor.equals("晋菜")) {
                            tables.findTableByIndex(tableCount - 1).jinFlavor -= delRecord.taste * delRecord.num;
                            tables.findTableByIndex(tableCount - 1).jinCount -= delRecord.num;
                        } else if (delRecord.dish.flavor.equals("浙菜")) {
                            tables.findTableByIndex(tableCount - 1).zheFlavor -= delRecord.taste * delRecord.num;
                            tables.findTableByIndex(tableCount - 1).zheCount -= delRecord.num;
                        }
                    }
                    tables.findTableByIndex(tableCount - 1).order.delARecordByOrderNum(orderNum);
                    // tables.findTableByIndex(tableCount - 1).order.deleteSentence(sb.toString());
                } else {
                    tables.findTableByIndex(tableCount - 1).order.addSentence("delete error;");
                }
            } else if (tableCount > 0 && str.matches("\\d+\\s\\d+\\s[\\u4e00-\\u9fa5]+\\s\\d\\s\\d+")) { // 代点普通菜
                int tableNum = Integer.parseInt(splitStr[0]);
                int orderNum = Integer.parseInt(splitStr[1]);
                int portion = Integer.parseInt(splitStr[3]);
                int num = Integer.parseInt(splitStr[4]);
                if (tables.findTableByNum(tableNum) != null) {
                    Dish dish = menu.searthDish(splitStr[2]);
                    if (dish == null) { // 没有这个菜
                        StringBuilder sb = new StringBuilder();
                        sb.append(splitStr[1]).append(" does not exist");
                        tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                    } else { // 有这个菜
                        if (dish.flavor == null) {
                            Record newRecord = tables.findTableByIndex(tableCount - 1).order.addARecord(orderNum, dish,
                                    orderNum, portion, num);
                            StringBuilder sb = new StringBuilder();
                            sb.append(orderNum).append(" table ")
                                    .append(tables.findTableByIndex(tableCount - 1).tableNum)
                                    .append(" pay for table ").append(tableNum).append(" ")
                                    .append(newRecord.getPrice());
                            tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                        } else {
                            tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                        }
                    }
                }
            } else if (tableCount > 0 && str.matches("\\d+\\s\\d+\\s[\\u4e00-\\u9fa5]+\\s\\d+\\s\\d\\s\\d+")) { // 代点特色菜
                int tableNum = Integer.parseInt(splitStr[0]);
                int orderNum = Integer.parseInt(splitStr[1]);
                int portion = Integer.parseInt(splitStr[4]);
                int num = Integer.parseInt(splitStr[5]);
                if (tables.findTableByNum(tableNum) != null) { // 有这个桌子
                    Dish dish = menu.searthDish(splitStr[2]);
                    if (dish == null) { // 没有这个菜
                        StringBuilder sb = new StringBuilder();
                        sb.append(splitStr[1]).append(" does not exist");
                        tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                    } else { // 有这个菜
                        if (dish.flavor != null) {
                            int taste = Integer.parseInt(splitStr[3]);
                            if (dish.flavor.equals("川菜")) {
                                if (taste < 0 || taste > 5) {
                                    StringBuilder sb = new StringBuilder();
                                    sb.append("spicy num out of range :");
                                    sb.append(taste);
                                    tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                                    continue;
                                } else {
                                    tables.findTableByNum(orderNum).chuanFlavor += taste * num;
                                    tables.findTableByNum(orderNum).chuanCount += num;
                                }
                            }
                            if (dish.flavor.equals("晋菜")) {
                                if (taste < 0 || taste > 4) {
                                    StringBuilder sb = new StringBuilder();
                                    sb.append("acidity num out of range :").append(taste);
                                    tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                                    continue;
                                } else {
                                    tables.findTableByNum(orderNum).jinFlavor += taste * num;
                                    tables.findTableByNum(orderNum).jinCount += num;
                                }
                            }
                            if (dish.flavor.equals("浙菜")) {
                                if (taste < 0 || taste > 3) {
                                    StringBuilder sb = new StringBuilder().append(taste);
                                    sb.append("sweetness num out of range :").append(taste);
                                    tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                                    continue;
                                } else {
                                    tables.findTableByNum(orderNum).zheFlavor += taste * num;
                                    tables.findTableByNum(orderNum).zheCount += num;
                                }
                            }
                        } else {
                            tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                        }
                        Record newRecord = tables.findTableByIndex(tableCount - 1).order.addARecord(orderNum, dish,
                                orderNum, portion,
                                num);
                        StringBuilder sb = new StringBuilder();
                        sb.append(orderNum).append(" table ").append(tables.findTableByIndex(tableCount - 1).tableNum)
                                .append(" pay for table ").append(tableNum).append(" ").append(newRecord.getPrice());
                        tables.findTableByIndex(tableCount - 1).order.addSentence(sb.toString());
                    }
                }
            } else {
                if (isTableError == false && tableCount == 0) {
                    System.out.println("wrong format");
                }
                if (tableCount > 0) {
                    tables.findTableByIndex(tableCount - 1).order.addSentence("wrong format");
                }
            }
        }
        sc.close();

        tables.showTables();
        customers.showCustomers(tables);
    }

    public static boolean checkTimeValidity(String date, String time) {
        int[] mon_maxnum = new int[] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        String[] dates = date.split("/");
        String[] times = time.split("/");
        int year = Integer.parseInt(dates[0]);
        int month = Integer.parseInt(dates[1]);
        int day = Integer.parseInt(dates[2]);
        int hour = Integer.parseInt(times[0]);
        int minute = Integer.parseInt(times[1]);
        int second = Integer.parseInt(times[2]);
        boolean flag = true;
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
            mon_maxnum[2] = 29;
        }
        if (month >= 1 && month <= 12) {
            if (day >= 1 && day <= mon_maxnum[month]) {
                if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59) {
                } else {
                    flag = false;
                }
            } else {
                flag = false;
            }
        } else {
            flag = false;
        }
        return flag;
    }

    public static boolean isDuringTime(int dayOfWeek, int hour, int minute, int second) {
        if (dayOfWeek >= 1 && dayOfWeek <= 5) {
            if (hour == 10) {
                if (minute >= 30 && minute < 60 && second >= 0 && second < 60) {
                    return true;
                }
            } else if (hour == 20 || hour == 14) {
                if (minute == 30 && second == 0) { // 20 : 30; 14 : 30
                    return true;
                } else if (minute >= 0 && minute < 30 && second >= 0 && second < 60) {
                    return true;
                } else {

                    return false;
                }
            } else if ((hour >= 17 && hour <= 19) || (hour >= 11 && hour <= 13)) {
                if (minute >= 0 && minute < 60 && second >= 0 && second < 60) {
                    return true;
                } else {
                    return false;
                }
            }
        } else if (dayOfWeek >= 6 && dayOfWeek <= 7) {
            if (hour == 9) {
                if (minute >= 30 && minute < 60 && second >= 0 && second < 60) {
                    return true;
                }
            } else if (hour == 21) {
                if (minute == 30 && second == 0) { // 21 : 30
                    return true;
                } else if (minute >= 0 && minute < 30 && second >= 0 && second < 60) {
                    return true;
                } else {
                    return false;
                }
            } else if (hour >= 10 && hour <= 20) {
                if (minute >= 0 && minute < 60 && second >= 0 && second < 60) {
                    return true;
                } else {
                    return false;
                }
            }
        }
        return false;
    }

    public static int getDayOfWeek(String date) { // 找星期几
        String[] arr = { "0", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
        Date dateUtil = new Date();
        SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");
        try {
            dateUtil = f.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int index = 0;
        String temp = dateUtil.toString();
        String[] temp1 = temp.split(" ");
        for (int i = 0; i < arr.length; i++) {
            if (temp1[0].equals(arr[i])) {
                index = i;
                break;
            }
        }
        return index;
    }

}
//

class Dish { // 菜品类:对应菜谱上一道菜的信息。
    String name;// 菜品名称

    int unit_price; // 单价

    String flavor; // 口味

    boolean isSpecialty; // 是否为特色菜

    public Dish() {

    }

    public Dish(String name, String flavor, int unit_price, boolean isSpecialty) {
        this.name = name;
        this.flavor = flavor;
        this.unit_price = unit_price;
        this.isSpecialty = isSpecialty;
    }

    int getPrice(int portion) {
        int price = 0;
        switch (portion) {
            case 1:
                price = unit_price;
                break;
            case 2:
                price = (int) Math.round((float) unit_price * 1.5);
                break;
            case 3:
                price = unit_price * 2;
                break;
        }
        return price;
    }
}

class Menu { // 菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
    Dish[] dishs = new Dish[100];// 菜品数组,保存所有菜品信息
    int count = 0;

    public Menu() {

    }

    public Dish searthDish(String dishName) { // 根据菜名在菜谱中查找菜品信息,返回Dish对象。
        for (int i = 0; i < count; i++) {
            if (dishName.equals(dishs[i].name)) { // 找得到
                return dishs[i];
            }
        }
        return null;
    }

    public Dish addDish(String dishName, String flavor, int unit_price, boolean isSpecialty) {// 添加一道菜品信息
        Dish newDish = new Dish(dishName, flavor, unit_price, isSpecialty);
        dishs[count] = newDish;
        count++;
        return newDish;
    }
}

class Record {// 点菜记录类:保存订单上的一道菜品记录
    int orderNum;// 序号

    Dish dish;// 菜品

    int taste; // 口味度值

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

    int num; // 份数

    public Record() {

    }

    public Record(int orderNum, Dish dish, int taste, int portion, int num) {
        this.orderNum = orderNum;
        this.dish = dish;
        this.taste = taste;
        this.portion = portion;
        this.num = num;
    }

    int getPrice() {// 计价,计算本条记录的价格
        return dish.getPrice(portion) * num;
    }
}

class Order { // 订单类:保存用户点的所有菜的信息。
    String[] sentences = new String[100]; // 保存语句
    Record[] records = new Record[100]; // 保存订单上每一道的记录
    int count = 0; // 订单个数
    int senCount = 0; // 语句个数

    public Order() {

    }

    public int getTotalPrice() { // 计算订单的总价
        int sum = 0;
        for (int i = 0; i < count; i++) {
            sum += records[i].getPrice();
        }
        return sum;
    }

    public int getNonSpecialtuPrice(int hour) { // 普通菜总价
        int sum = 0;
        double discount = 0;
        if (hour >= 10 && hour <= 14) {
            discount = 0.6;
        } else if (hour >= 17 && hour <= 20) {
            discount = 0.8;
        }
        for (int i = 0; i < count; i++) {
            if (!records[i].dish.isSpecialty) {
                sum += (int) Math.round((double) records[i].getPrice() * discount);
            }
        }
        return sum;
    }

    public int getSpecialtyPrice() { // 特色菜总价
        int sum = 0;
        for (int i = 0; i < count; i++) {
            if (records[i].dish.isSpecialty) {
                sum += (int) Math.round((double) records[i].getPrice() * 0.7);
            }
        }
        return sum;
    }

    public Record addARecord(int orderNum, Dish dish, int taste, int portion, int num) {// 添加一条菜
        Record newRecord = new Record(orderNum, dish, taste, portion, num);
        records[count] = newRecord;
        count++;
        return newRecord;
    }

    public void delARecordByOrderNum(int orderNum) {// 根据序号删除一条记录
        for (int i = 0; i < count; i++) {
            if (orderNum == records[i].orderNum) { // 有删除序号
                for (int j = i; j < count; j++) {
                    records[j] = records[j + 1];
                }
                count--;
                break;
            }
        }
    }

    public Record findRecordByNum(int orderNum) {// 根据序号查找一条记录
        for (int i = 0; i < count; i++) {
            if (orderNum == records[i].orderNum) {
                return records[i];
            }
        }
        return null;
    }

    // public Record findRecordByName(String name) {
    // for (int i = 0; i < count; i++) {
    // if (name.equals(records[i].name)) {
    // return records[i];
    // }
    // }
    // return null;
    // }

    public void addSentence(String str) {
        sentences[senCount] = str;
        senCount++;
    }

    public void deleteSentence(String str) {
        for (int i = 0; i < senCount; i++) {
            if (str.equals(sentences[i])) {
                for (int j = i; j < senCount; j++) {
                    sentences[j] = sentences[j + 1];
                }
                break;
            }
        }
        senCount--;
    }

    public void showSentence() {
        for (int i = 0; i < senCount; i++) {
            System.out.println(sentences[i]);
        }
    }

}

class Table { // 桌类:保存一桌的信息
    int tableNum; // 桌号

    int year;
    int month;
    int day;

    int hour;
    int minute;
    int second;

    Order order;

    String customerName;

    int dayOfWeek;

    int chuanFlavor = 0;
    int chuanCount = 0;
    int jinFlavor = 0;
    int jinCount = 0;
    int zheFlavor = 0;
    int zheCount = 0;

    String[] dayOfWeekStrings = { "0", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };

    public Table() { // 无参构造方法

    }

    public Table(int tableNum, int year, int month, int day, int hour, int minute, int second, int dayOfWeek,
            Order order, String customerName) { // 带参构造方法
        this.tableNum = tableNum;
        this.year = year;
        this.month = month;
        this.day = day;
        this.hour = hour;
        this.minute = minute;
        this.second = second;
        this.dayOfWeek = dayOfWeek;
        this.order = order;
        this.customerName = customerName;
    }

    public int getOriginalPrice() {
        return order.getTotalPrice();
    }

    public int getDiscountPrice() {
        if (dayOfWeek >= 6 && dayOfWeek <= 7) {
            return order.getTotalPrice();
        } else if (dayOfWeek >= 1 && dayOfWeek <= 5) {
            return order.getNonSpecialtuPrice(hour) + order.getSpecialtyPrice();
        }
        return 0;
    }

}

class Tables { // 保存每桌的信息
    Table[] table = new Table[100];
    int count = 0;

    public Tables() {

    }

    public Table addTable(int tableNum, int year, int month, int day,
            int hour, int minute, int second, int dayOfWeek, String customerName) {
        Table newTable = new Table(tableNum, year, month, day, hour, minute, second, dayOfWeek, new Order(),
                customerName);
        table[count] = newTable;
        count++;
        return null;
    }

    public Table findTableByNum(int tableNum) { // 序号找桌子
        for (int i = 0; i < count; i++) {
            if (tableNum == table[i].tableNum) {
                return table[i];
            }
        }
        return null;
    }

    public Table findTableByIndex(int index) { // 添加顺序找桌子
        return table[index];
    }

    public int getTotalPriceByCustomerName(String name) { // 按桌主名称算总价
        int sum = 0;
        for (int i = 0; i < count; i++) {
            if (name.equals(table[i].customerName)) {
                sum += table[i].getDiscountPrice();
            }
        }
        return sum;
    }

    public void showTables() {
        String[] averageChuanFlavor = { " 不辣", " 微辣", " 稍辣", " 辣", " 很辣", " 爆辣" };
        String[] averageJinFlavor = { " 不酸", " 微酸", " 稍酸", " 酸", " 很酸" };
        String[] averageZheFlavor = { " 不甜", " 微甜", " 稍甜", " 甜" };
        for (int i = 0; i < count; i++) {
            table[i].order.showSentence();
        }
        boolean isAddSpace = true;
        for (int i = 0; i < count; i++) {
            isAddSpace = true;
            StringBuilder sb = new StringBuilder();
            sb.append("table ").append(table[i].tableNum).append(": ").append(table[i].getOriginalPrice()).append(" ")
                    .append(table[i].getDiscountPrice());
            if (table[i].chuanCount != 0) {
                isAddSpace = false;
                int average = (int) Math.round((float) table[i].chuanFlavor / (float) table[i].chuanCount);
                sb.append(" 川菜 ").append(table[i].chuanCount).append(averageChuanFlavor[average]);
            }
            if (table[i].jinCount != 0) {
                isAddSpace = false;
                int average = (int) Math.round((float) table[i].jinFlavor / (float) table[i].jinCount);
                sb.append(" 晋菜 ").append(table[i].jinCount).append(averageJinFlavor[average]);
            }
            if (table[i].zheCount != 0) {
                isAddSpace = false;
                int average = (int) Math.round((float) table[i].zheFlavor / (float) table[i].zheCount);
                sb.append(" 浙菜 ").append(table[i].zheCount).append(averageZheFlavor[average]);
            }
            if (isAddSpace) {
                sb.append(" ");
            }
            System.out.println(sb.toString());
        }
    }

}

class Customer {
    String name;
    String phone;

    public Customer() {

    }

    public Customer(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }
}

class Customers {
    Customer[] customers = new Customer[100];
    int customerCount = 0;
    String[] names = new String[100];
    int nameCount = 0;

    public Customers() {

    }

    public Customer addCustomer(String name, String phone) {
        Customer newCustomer = new Customer(name, phone);
        customers[customerCount] = newCustomer;
        customerCount++;
        names[nameCount] = name;
        nameCount++;
        return newCustomer;
    }

    public Customer findCustomerByName(String name) {
        for (int i = 0; i < customerCount; i++) {
            if (name.equals(customers[i].name)) {
                return customers[i];
            }
        }
        return null;
    }

    public void sortNames() {
        for (int i = 0; i < nameCount; i++) {
            int k = i;
            for (int j = i + 1; j < nameCount; j++) {
                if (names[j].compareToIgnoreCase(names[k]) < 0) {
                    k = j;
                }
            }
            String temp = names[i];
            names[i] = names[k];
            names[k] = temp;
        }
    }

    public void showCustomers(Tables tables) {
        sortNames();
        for (int i = 0; i < customerCount; i++) {
            StringBuilder sb = new StringBuilder();
            Customer customer = findCustomerByName(names[i]);
            sb.append(names[i]).append(" ").append(customer.phone).append(" ")
                    .append(tables.getTotalPriceByCustomerName(names[i]));
            System.out.println(sb.toString());
        }
    }
}

OOP训练集08 7-1 课程成绩统计程序-1
类图如下:

设计分析与心得
课程成绩统计程序系列第一次程序,相较于上一个系列菜单计价程序,题目要求,包括输入、输出等更为清晰,完成过程十分顺利。
Class_类:用于储存班级的信息(班级编号),班级里有学生,能根据学生学号查找一个学生,能根据学生课程成绩计算该班级的平均分,能根据班级平均分从低到高对班级进行比较,以便后续进行排序输出,能输出学生的信息以及课程平均分,若该学生没有参加任何考试,则输出学生信息+“did not take any exams”。
Student类:用于储存学生的信息(学生学号、学生姓名、学生课程成绩、参与考试的个数),能根据学生学号从低到高对学生进行比较,以便后续进行排序,如果学生参与的考试个数不为零,则计算该学生的平均分。
School类:为了储存班级而创建出的一个类,能根据班级办好查找该班级,能输出班级排序后的班级信息以及平均分、若班级没有考试信息,则输出班级信息+“did not take any exams”。
Course类:用于储存课程信息(课程名称,课程性质、课程考核方式),能根据课程名称,从低到高进行比较,以便后续进行排序。
Curriculum类:为了储存课程而创建出的一个类,能添加一个课程信息,通过课程名称查找一个课程,并能对课程进行排序。
Score类:用于储存学生的成绩,并能根据成绩信息和权重值,计算期末总成绩。
ExamScore类、TestScore类继承Score类,属于两种不同的课程性质,ExamSocre类对应考试、TestScore类对应考察。
SelectCourse类:学生进行选课,其中含有学生、课程、课程成绩。
TheSystem类:为了储存选课信息而创建出的一个类,能添加一个选课信息,能通过学生学号、学生名称、考试名称判断选课信息是否重复,能输出课程信息以及课程平均分,若该课程没有考试信息,则输出课程信息+“has no grade yet”。
源码如下:

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        School school = new School();
        Curriculum curr = new Curriculum();
        TheSystem theSystem = new TheSystem();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            String str = scanner.nextLine();
            if (str.equals("end")) {
                break;
            }
            String[] splitStr = str.split(" ");
            if (str.matches("[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s(选修|必修)\\s(考试|考察)")) {
                String couName = splitStr[0];
                String des = splitStr[1];
                String type = splitStr[2];
                if (splitStr[1].equals("必修") && splitStr[2].equals("考试")) {
                    if (curr.findCourseByName(couName) == null) {
                        curr.addCourse(new Course(couName, des, type));
                    }
                } else if (splitStr[1].equals("选修")) {
                    if (curr.findCourseByName(couName) == null) {
                        curr.addCourse(new Course(couName, des, type));
                    }
                } else { // 必修课考察情况
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" : course type & access mode mismatch");
                    System.out.println(sb);
                }
            } else if (str.matches("[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s(选修|必修)")) {
                String couName = splitStr[0];
                String des = splitStr[1];
                if (des.equals("必修")) {
                    if (curr.findCourseByName(couName) == null) {
                        curr.addCourse(new Course(couName, des, "考试"));
                    }
                } else { // 选修课无考核方式
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" : course type & access mode mismatch");
                    System.out.println(sb);
                }
            } else if (str.matches(
                    "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s([0-9]|[1-9][0-9]|100)\\s([0-9]|[1-9][0-9]|100)")) { // 考试
                String stuId = splitStr[0];
                String claId = splitStr[0].substring(0, 6);
                String stuName = splitStr[1];
                String couName = splitStr[2];
                int grade = 0;
                int performance = 0;

                if (curr.findCourseByName(couName) != null) {
                    if (curr.findCourseByName(couName).getExamType().equals("考试")) {
                        grade = Integer.parseInt(splitStr[4]);
                        performance = Integer.parseInt(splitStr[3]);
                    } else {
                        grade--;
                        StringBuilder sb = new StringBuilder();
                        sb.append(stuId).append(" ").append(stuName).append(" ")
                                .append(": access mode mismatch");
                        System.out.println(sb);
                    }
                } else {
                    grade--;
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" does not exist");
                    System.out.println(sb);
                }

                if (school.findClass_ByID(claId) == null) {
                    school.addClass(new Class_(claId));
                }
                if (school.findClass_ByID(claId).findStudentByName(stuName) == null) {
                    school.findClass_ByID(claId)
                            .addStudent(new Student(stuId, stuName, 0, 0));
                }
                if (!theSystem.hasSame(stuId, stuName, couName) && grade >= 0) {
                    school.findClass_ByID(claId).findStudentByName(stuName)
                            .addTotalScore((int) (performance * 0.3 + grade * 0.7));
                    theSystem.addSelectCourse(
                            new SelectCourse(curr.findCourseByName(couName),
                                    new ExamScore(performance, grade),
                                    school.findClass_ByID(claId).findStudentByName(stuName)));
                }
            } else if (str.matches(
                    "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s([0-9]|[1-9][0-9]|100)")) { // 考察
                String stuId = splitStr[0];
                String claId = splitStr[0].substring(0, 6);
                String stuName = splitStr[1];
                String couName = splitStr[2];
                int grade = 0;

                if (curr.findCourseByName(couName) != null) {
                    if (curr.findCourseByName(couName).getExamType().equals("考察")) {
                        grade = Integer.parseInt(splitStr[3]);
                    } else {
                        grade--;
                        StringBuilder sb = new StringBuilder();
                        sb.append(stuId).append(" ").append(stuName).append(" ")
                                .append(": access mode mismatch");
                        System.out.println(sb);
                    }
                } else {
                    grade--;
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" does not exist");
                    System.out.println(sb);
                }

                if (school.findClass_ByID(claId) == null) {
                    school.addClass(new Class_(claId));
                }
                if (school.findClass_ByID(claId).findStudentByName(stuName) == null) {
                    school.findClass_ByID(claId)
                            .addStudent(new Student(stuId, stuName, 0, 0));
                }
                if (!theSystem.hasSame(stuId, stuName, couName) && grade >= 0) {
                    school.findClass_ByID(claId).findStudentByName(stuName)
                            .addTotalScore(grade);
                    theSystem.addSelectCourse(
                            new SelectCourse(curr.findCourseByName(couName),
                                    new TestScore(grade),
                                    school.findClass_ByID(claId).findStudentByName(stuName)));
                }
            } else {
                System.out.println("wrong format");
            }
        }
        scanner.close();
        school.showStudents();
        theSystem.showCourses(curr);
        school.showClass_es();
    }
}

class School {
    private ArrayList<Class_> class_es = new ArrayList<>();

    public School() {

    }

    public void addClass(Class_ class_) {
        this.class_es.add(class_);
    }

    public Class_ findClass_ByID(String classId) {
        int size = class_es.size();
        for (int i = 0; i < size; i++) {
            if (class_es.get(i).getClassId().equals(classId)) {
                return class_es.get(i);
            }
        }
        return null;
    }

    public void showClass_es() {
        Collections.sort(class_es);
        for (Class_ c : class_es) {
            StringBuilder sb = new StringBuilder();
            sb.append(c.getClassId());
            if (c.getNum() == 0) {
                sb.append(" has no grades yet");
            } else {
                sb.append(" ").append(c.getAverageScore());
            }
            System.out.println(sb);
        }
    }

    public void showStudents() {
        Collections.sort(class_es);
        for (Class_ class_ : class_es) {
            class_.showStudents();
        }
    }
}

class Class_ implements Comparable<Class_> {
    private ArrayList<Student> students = new ArrayList<>();

    private String classId;

    public Class_() {

    }

    public Class_(String classId) {
        this.classId = classId;
    }

    public String getClassId() {
        return classId;
    }

    public void setClass(String classId) {
        this.classId = classId;
    }

    public void addStudent(Student student) {
        this.students.add(student);
    }

    public int getNum() {
        int num = 0;
        for (Student student : students) {
            num += student.getCnt();
        }
        return num;
    }

    public Student findStudentByName(String n) {
        int size = students.size();
        for (int i = 0; i < size; i++) {
            if (students.get(i).getName().equals(n)) {
                return students.get(i);
            }
        }
        return null;
    }

    public int getAverageScore() { // 计算班级平均分
        int totalScore = 0;
        int cnt = 0;
        for (Student student : students) {
            cnt += student.getCnt();
            totalScore += student.getTotalScore();
        }
        return totalScore / cnt;
    }

    public void showStudents() {
        Collections.sort(students);
        for (Student s : students) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getId()).append(" ").append(s.getName());
            if (s.getCnt() == 0) {
                sb.append(" did not take any exams");
            } else {
                sb.append(" ").append(s.getAverageScore());
            }
            System.out.println(sb);
        }
    }

    @Override
    public int compareTo(Class_ o) {
        return this.getClassId().compareToIgnoreCase(o.getClassId());
    }
}

class Student implements Comparable<Student> {
    private String id;
    private String name;
    private int totalScore;
    private int cnt;

    public Student() {

    }

    public Student(String id, String name, int totalScore, int cnt) {
        this.id = id;
        this.name = name;
        this.totalScore = totalScore;
        this.cnt = cnt;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getTotalScore() {
        return totalScore;
    }

    public void setTotalScore(int totalScore) {
        this.totalScore = totalScore;
    }

    public int getCnt() {
        return cnt;
    }

    public void setCnt(int cnt) {
        this.cnt = cnt;
    }

    public void addTotalScore(int score) {
        cnt++;
        totalScore += score;
    }

    public int getAverageScore() {
        return totalScore / cnt;
    }

    @Override
    public int compareTo(Student o) {
        return this.getId().compareToIgnoreCase(o.getId());
    }
}

class Curriculum {
    private ArrayList<Course> courses = new ArrayList<>();

    public Curriculum() {

    }

    public void addCourse(Course course) {
        courses.add(course);
    }

    public Course findCourseByName(String name) {
        if (courses.isEmpty()) {
            return null;
        }
        for (Course course : courses) {
            if (course.getName().equals(name)) {
                return course;
            }
        }
        return null;
    }

    public ArrayList<Course> getCourses() {
        Collections.sort(courses);
        return courses;
    }
}

class Course implements Comparable<Course> {
    private String name;
    private String description;
    private String examType;

    public Course() {

    }

    public Course(String name, String description, String examType) {
        this.name = name;
        this.description = description;
        this.examType = examType;
    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getExamType() {
        return examType;
    }

    public void setExamType(String type) {
        this.examType = type;
    }

    @Override
    public int compareTo(Course o) {
        Collator instance = Collator.getInstance(Locale.CHINA);
        return instance.compare(this.name, o.getName());
    }
}

abstract class Score {
    private int grade;

    public Score() {

    }

    public Score(int grade) {
        this.grade = grade;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int score) {
        this.grade = score;
    }

    abstract public int getFinalScore();
}

class ExamScore extends Score {
    private int performance;

    public ExamScore() {
        super();
    }

    public ExamScore(int performance, int grade) {
        super(grade);
        this.performance = performance;
    }

    public int getPerformance() {
        return performance;
    }

    public void setPerformance(int performance) {
        this.performance = performance;
    }

    @Override
    public int getFinalScore() {
        return (int) (this.performance * 0.3 + this.getGrade() * 0.7);
    }
}

class TestScore extends Score {
    public TestScore() {

    }

    public TestScore(int grade) {
        super(grade);
    }

    @Override
    public int getFinalScore() {
        return this.getGrade();
    }
}

class TheSystem {
    private ArrayList<SelectCourse> selectCourses = new ArrayList<>();

    public TheSystem() {

    }

    public void addSelectCourse(SelectCourse s) {
        this.selectCourses.add(s);
    }

    public boolean hasSame(String id, String stu, String cou) {
        if (selectCourses.isEmpty()) {
            return false;
        }
        for (SelectCourse s : selectCourses) {
            if (s.getStudent().getId().equals(id)
                    && s.getStudent().getName().equals(stu)
                    && s.getCourse().getName().equals(cou)) {
                return true;
            }
        }
        return false;
    }

    public void showCourses(Curriculum cur) {
        ArrayList<Course> courses = cur.getCourses();
        for (Course course : courses) {
            StringBuilder sb = new StringBuilder();
            sb.append(course.getName()).append(" ");
            int per = 0;
            int grade = 0;
            int fin = 0;
            int cnt = 0;
            boolean hasPer = false;

            for (SelectCourse selectCourse : selectCourses) {
                if (selectCourse.getCourse().equals(course)) {
                    cnt++;
                    grade += selectCourse.getScore().getGrade();
                    fin += selectCourse.getScore().getFinalScore();
                    if (selectCourse.getScore() instanceof ExamScore) {
                        ExamScore children = (ExamScore) selectCourse.getScore();
                        per += children.getPerformance();
                        hasPer = true;
                    }
                }
            }
            if (cnt == 0) {
                sb.append("has no grades yet");
            } else {
                if (hasPer) {
                    sb.append(per / cnt).append(" ").append(grade / cnt).append(" ").append(fin / cnt);
                } else {
                    sb.append(grade / cnt).append(" ").append(fin / cnt);
                }
            }
            System.out.println(sb);
        }
    }
}

class SelectCourse implements Comparable<SelectCourse> {
    private Course course;
    private Score score;
    private Student student;

    public SelectCourse() {

    }

    public SelectCourse(Course course, Score score, Student student) {
        this.course = course;
        this.score = score;
        this.student = student;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public Score getScore() {
        return score;
    }

    public void setScore(Score score) {
        this.score = score;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public int compareTo(SelectCourse o) {
        return this.getStudent().getId().compareTo(o.getStudent().getId());
    }
}

OOP训练集10 7-3 课程成绩统计程序-2
类图如下:

设计分析与心得
由于上一次程序写的比较多,而且新添加的内容也不多,这次很顺利。
在Main类中多加了一条if else语句判断实验。
新添加一个ExperimentalScore类储存实验各次成绩,并能计算实验平均成绩。
然后在输出成绩信息时,多加一个实验类型成绩输出。
就做完了。
源码如下:

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        School school = new School();
        Curriculum curr = new Curriculum();
        TheSystem theSystem = new TheSystem();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            String str = scanner.nextLine();
            if (str.equals("end")) {
                break;
            }
            String[] splitStr = str.split(" ");
            if (str.matches("[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s(选修|必修|实验)\\s(考试|考察|实验)")) {
                String couName = splitStr[0];
                String des = splitStr[1];
                String type = splitStr[2];
                if (des.equals("必修") && type.equals("考试")) {
                    if (curr.findCourseByName(couName) == null) {
                        curr.addCourse(new Course(couName, des, type));
                    }
                } else if (des.equals("实验") && type.equals("实验")) {
                    curr.addCourse(new Course(couName, "实验", "实验"));
                } else if (des.equals("选修") && !type.equals("实验")) {
                    if (curr.findCourseByName(couName) == null) {
                        curr.addCourse(new Course(couName, des, type));
                    }
                } else {
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" : course type & access mode mismatch");
                    System.out.println(sb);
                }
            } else if (str.matches("[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s(选修|必修)")) {
                String couName = splitStr[0];
                String des = splitStr[1];
                if (des.equals("必修")) {
                    if (curr.findCourseByName(couName) == null) {
                        curr.addCourse(new Course(couName, des, "考试"));
                    }
                } else { // 选修课无考核方式
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" : course type & access mode mismatch");
                    System.out.println(sb);
                }
            } else if (str.matches(
                    "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s([0-9]|[1-9][0-9]|100)\\s([0-9]|[1-9][0-9]|100)")) { // 考试
                String stuId = splitStr[0];
                String claId = splitStr[0].substring(0, 6);
                String stuName = splitStr[1];
                String couName = splitStr[2];
                int grade = 0;
                int performance = 0;

                if (curr.findCourseByName(couName) != null) {
                    if (curr.findCourseByName(couName).getExamType().equals("考试")) {
                        grade = Integer.parseInt(splitStr[4]);
                        performance = Integer.parseInt(splitStr[3]);
                    } else {
                        grade--;
                        StringBuilder sb = new StringBuilder();
                        sb.append(stuId).append(" ").append(stuName).append(" ")
                                .append(": access mode mismatch");
                        System.out.println(sb);
                    }
                } else {
                    grade--;
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" does not exist");
                    System.out.println(sb);
                }

                if (school.findClass_ByID(claId) == null) {
                    school.addClass(new Class_(claId));
                }
                if (school.findClass_ByID(claId).findStudentByName(stuName) == null) {
                    school.findClass_ByID(claId)
                            .addStudent(new Student(stuId, stuName, 0, 0));
                }
                if (theSystem.hasSame(stuId, stuName, couName) == null && grade >= 0) {
                    school.findClass_ByID(claId).findStudentByName(stuName)
                            .addTotalScore((int) (performance * 0.3 + grade * 0.7));
                    theSystem.addSelectCourse(
                            new SelectCourse(curr.findCourseByName(couName),
                                    new ExamScore(performance, grade),
                                    school.findClass_ByID(claId).findStudentByName(stuName)));
                }
            } else if (str.matches(
                    "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s([0-9]|[1-9][0-9]|100)")) { // 考察
                String stuId = splitStr[0];
                String claId = splitStr[0].substring(0, 6);
                String stuName = splitStr[1];
                String couName = splitStr[2];
                int grade = 0;

                if (curr.findCourseByName(couName) != null) {
                    if (curr.findCourseByName(couName).getExamType().equals("考察")) {
                        grade = Integer.parseInt(splitStr[3]);
                    } else {
                        grade--;
                        StringBuilder sb = new StringBuilder();
                        sb.append(stuId).append(" ").append(stuName).append(" ")
                                .append(": access mode mismatch");
                        System.out.println(sb);
                    }
                } else {
                    grade--;
                    StringBuilder sb = new StringBuilder();
                    sb.append(couName).append(" does not exist");
                    System.out.println(sb);
                }

                if (school.findClass_ByID(claId) == null) {
                    school.addClass(new Class_(claId));
                }
                if (school.findClass_ByID(claId).findStudentByName(stuName) == null) {
                    school.findClass_ByID(claId)
                            .addStudent(new Student(stuId, stuName, 0, 0));
                }
                if (theSystem.hasSame(stuId, stuName, couName) == null && grade >= 0) {
                    school.findClass_ByID(claId).findStudentByName(stuName)
                            .addTotalScore(grade);
                    theSystem.addSelectCourse(
                            new SelectCourse(curr.findCourseByName(couName),
                                    new TestScore(grade),
                                    school.findClass_ByID(claId).findStudentByName(stuName)));
                }
            } else if (str.matches(
                    "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z]{1,10}\\s[0-9]+(\\s[0-9]+)+")) { // 实验
                String stuId = splitStr[0];
                String claId = splitStr[0].substring(0, 6);
                String stuName = splitStr[1];
                String couName = splitStr[2];
                int num = Integer.parseInt(splitStr[3]);
                int cnt = 0;
                boolean hasWrong = false;
                boolean courseExists = false;
                for (int i = 4; i < splitStr.length; i++) {
                    int grade = Integer.parseInt(splitStr[i]);
                    if (grade >= 0 && grade <= 100) {
                        cnt++;
                    } else {
                        hasWrong = true;
                    }
                }

                if (curr.findCourseByName(couName) != null) {
                    courseExists = true;
                } else {
                    if (!hasWrong) {
                        StringBuilder sb = new StringBuilder();
                        sb.append(couName).append(" does not exist");
                        System.out.println(sb);
                    }
                }

                if (!hasWrong && num >= 4 && num <= 9) {
                    if (school.findClass_ByID(claId) == null) {
                        school.addClass(new Class_(claId));
                    }
                    if (school.findClass_ByID(claId).findStudentByName(stuName) == null) {
                        school.findClass_ByID(claId)
                                .addStudent(new Student(stuId, stuName, 0, 0));
                    }
                    if (cnt == num) {
                        if (courseExists) {
                            for (int i = 4; i < splitStr.length; i++) {
                                int grade = Integer.parseInt(splitStr[i]);
                                if (theSystem.hasSame(stuId, stuName, couName) == null) {
                                    theSystem.addSelectCourse(
                                            new SelectCourse(curr.findCourseByName(couName),
                                                    new ExperimentalScore(0),
                                                    school.findClass_ByID(claId).findStudentByName(stuName)));
                                }
                                if (theSystem.hasSame(stuId, stuName, couName)
                                        .getScore() instanceof ExperimentalScore) {
                                    ExperimentalScore children = (ExperimentalScore) theSystem
                                            .hasSame(stuId, stuName, couName)
                                            .getScore();
                                    children.addScore(grade);
                                    school.findClass_ByID(claId).findStudentByName(stuName)
                                            .addTotalScore(grade);
                                }
                            }
                        }
                    } else {
                        StringBuilder sb = new StringBuilder();
                        sb.append(stuId).append(" ").append(stuName).append(" ")
                                .append(": access mode mismatch");
                        System.out.println(sb);
                    }
                } else {
                    if (num < 4) {
                        System.out.println("wrong format");
                    }
                    for (int i = 4; i < splitStr.length; i++) {
                        int grade = Integer.parseInt(splitStr[i]);
                        if (grade < 0 || grade > 100) {
                            System.out.println("wrong format");
                        }
                    }
                }
            } else {
                System.out.println("wrong format");
            }
        }
        scanner.close();
        school.showStudents();
        theSystem.showCourses(curr);
        school.showClass_es();
    }
}

class School {
    private ArrayList<Class_> class_es = new ArrayList<>();

    public School() {

    }

    public void addClass(Class_ class_) {
        this.class_es.add(class_);
    }

    public Class_ findClass_ByID(String classId) {
        if (class_es.size() == 0) {
            return null;
        }
        for (Class_ class_ : class_es) {
            if (class_.getClassId().equals(classId)) {
                return class_;
            }
        }
        return null;
    }

    public void showClass_es() {
        Collections.sort(class_es);
        for (Class_ c : class_es) {
            StringBuilder sb = new StringBuilder();
            sb.append(c.getClassId());
            if (c.getNum() == 0) {
                sb.append(" has no grades yet");
            } else {
                sb.append(" ").append(c.getAverageScore());
            }
            System.out.println(sb);
        }
    }

    public void showStudents() {
        Collections.sort(class_es);
        for (Class_ class_ : class_es) {
            class_.showStudents();
        }
    }
}

class Class_ implements Comparable<Class_> {
    private ArrayList<Student> students = new ArrayList<>();

    private String classId;

    public Class_() {

    }

    public Class_(String classId) {
        this.classId = classId;
    }

    public String getClassId() {
        return classId;
    }

    public void setClass(String classId) {
        this.classId = classId;
    }

    public void addStudent(Student student) {
        this.students.add(student);
    }

    public int getNum() {
        int num = 0;
        for (Student student : students) {
            num += student.getCnt();
        }
        return num;
    }

    public Student findStudentByName(String s) {
        if (students.size() == 0) {
            return null;
        }
        for (Student student : students) {
            if (student.getName().equals(s)) {
                return student;
            }
        }
        return null;
    }

    public int getAverageScore() { // 计算班级平均分
        int totalScore = 0;
        int cnt = 0;
        for (Student student : students) {
            if (student.getCnt() != 0) {
                cnt++;
                totalScore += student.getAverageScore();
            }
        }
        return totalScore / cnt;
    }

    public void showStudents() {
        Collections.sort(students);
        for (Student s : students) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getId()).append(" ").append(s.getName());
            if (s.getCnt() == 0) {
                sb.append(" did not take any exams");
            } else {
                sb.append(" ").append(s.getAverageScore());
            }
            System.out.println(sb);
        }
    }

    @Override
    public int compareTo(Class_ o) {
        return this.getClassId().compareToIgnoreCase(o.getClassId());
    }
}

class Student implements Comparable<Student> {
    private String id;
    private String name;
    private int totalScore;
    private int cnt;

    public Student() {

    }

    public Student(String id, String name, int totalScore, int cnt) {
        this.id = id;
        this.name = name;
        this.totalScore = totalScore;
        this.cnt = cnt;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getTotalScore() {
        return totalScore;
    }

    public void setTotalScore(int totalScore) {
        this.totalScore = totalScore;
    }

    public int getCnt() {
        return cnt;
    }

    public void setCnt(int cnt) {
        this.cnt = cnt;
    }

    public void addTotalScore(int score) {
        cnt++;
        totalScore += score;
    }

    public int getAverageScore() {
        return totalScore / cnt;
    }

    @Override
    public int compareTo(Student o) {
        return this.getId().compareToIgnoreCase(o.getId());
    }
}

class Curriculum {
    private ArrayList<Course> courses = new ArrayList<>();

    public Curriculum() {

    }

    public void addCourse(Course course) {
        courses.add(course);
    }

    public Course findCourseByName(String name) {
        if (courses.isEmpty()) {
            return null;
        }
        for (Course course : courses) {
            if (course.getName().equals(name)) {
                return course;
            }
        }
        return null;
    }

    public ArrayList<Course> getCourses() {
        Collections.sort(courses);
        return courses;
    }
}

class Course implements Comparable<Course> {
    private String name;
    private String description;
    private String examType;

    public Course() {

    }

    public Course(String name, String description, String examType) {
        this.name = name;
        this.description = description;
        this.examType = examType;
    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getExamType() {
        return examType;
    }

    public void setExamType(String type) {
        this.examType = type;
    }

    @Override
    public int compareTo(Course o) {
        Collator instance = Collator.getInstance(Locale.CHINA);
        return instance.compare(this.name, o.getName());
    }
}

abstract class Score {
    private int grade;

    public Score() {

    }

    public Score(int grade) {
        this.grade = grade;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int score) {
        this.grade = score;
    }

    abstract public int getFinalScore();
}

class ExamScore extends Score {
    private int performance;

    public ExamScore() {
        super();
    }

    public ExamScore(int performance, int grade) {
        super(grade);
        this.performance = performance;
    }

    public int getPerformance() {
        return performance;
    }

    public void setPerformance(int performance) {
        this.performance = performance;
    }

    @Override
    public int getFinalScore() {
        return (int) (this.performance * 0.3 + this.getGrade() * 0.7);
    }
}

class TestScore extends Score {
    public TestScore() {
        super();
    }

    public TestScore(int grade) {
        super(grade);
    }

    @Override
    public int getFinalScore() {
        return this.getGrade();
    }
}

class ExperimentalScore extends Score {
    ArrayList<Integer> scores = new ArrayList<Integer>();

    public ExperimentalScore() {
        super();
    }

    public ExperimentalScore(int grade) {
        super(grade);
    }

    public void addScore(int s) {
        scores.add(s);
        this.setGrade(this.getGrade() + s);
    }

    public int getSize() {
        return scores.size();
    }

    @Override
    public int getFinalScore() {
        return (int) (this.getGrade() / scores.size());
    }
}

class TheSystem {
    private HashSet<SelectCourse> selectCourses = new HashSet<>();

    public TheSystem() {

    }

    public void addSelectCourse(SelectCourse s) {
        this.selectCourses.add(s);
    }

    public SelectCourse hasSame(String id, String stu, String cou) {
        if (selectCourses.isEmpty()) {
            return null;
        }
        for (SelectCourse s : selectCourses) {
            if (s.getStudent().getId().equals(id)
                    && s.getStudent().getName().equals(stu)
                    && s.getCourse().getName().equals(cou)) {
                return s;
            }
        }
        return null;
    }

    public void showCourses(Curriculum cur) {
        ArrayList<Course> courses = cur.getCourses();
        for (Course course : courses) {
            StringBuilder sb = new StringBuilder();
            sb.append(course.getName()).append(" ");
            int per = 0;
            int grade = 0;
            int fin = 0;
            int cnt = 0;
            boolean hasPer = false;
            boolean hasGrade = false;

            for (SelectCourse selectCourse : selectCourses) {
                if (selectCourse.getCourse().equals(course)) {
                    cnt++;
                    if (selectCourse.getScore() instanceof TestScore
                            || selectCourse.getScore() instanceof ExamScore) {
                        grade += selectCourse.getScore().getGrade();
                        hasGrade = true;
                    }
                    fin += selectCourse.getScore().getFinalScore();
                    if (selectCourse.getScore() instanceof ExamScore) {
                        ExamScore children = (ExamScore) selectCourse.getScore();
                        per += children.getPerformance();
                        hasPer = true;
                    }
                }
            }
            if (cnt == 0) {
                sb.append("has no grades yet");
            } else {
                if (hasPer) {
                    sb.append(per / cnt).append(" ").append(grade / cnt).append(" ").append(fin / cnt);
                } else if (hasGrade) {
                    sb.append(grade / cnt).append(" ").append(fin / cnt);
                } else {
                    sb.append(fin / cnt);
                }
            }
            System.out.println(sb);
        }
    }
}

class SelectCourse implements Comparable<SelectCourse> {
    private Course course;
    private Score score;
    private Student student;

    public SelectCourse() {

    }

    public SelectCourse(Course course, Score score, Student student) {
        this.course = course;
        this.score = score;
        this.student = student;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public Score getScore() {
        return score;
    }

    public void setScore(Score score) {
        this.score = score;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public int compareTo(SelectCourse o) {
        return this.getStudent().getId().compareTo(o.getStudent().getId());
    }
}

OOP训练集11 7-2 课程成绩统计程序-3
类图如下:

设计分析与心得
课程成绩统计程序-2相比,修改了计算总成绩的方式,但是这一改,就出现了一个难以寻找的问题

我想应该就是成绩计算出现的问题,不同方式的计算,再加上编译器的特性,会出现不同的误差。
源码如下:

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Curriculum curriculum = new Curriculum();
        TheSystem theSystem = new TheSystem();
        School school = new School();
        while (true) {
            String input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            }
            String[] tokens = input.split("\\s+");
            if (input.matches("[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验).*?")) { // 课程信息
                String courseName = tokens[0];
                String description = tokens[1];
                String type = tokens[2];
                if (description.equals("必修") && type.equals("考试")) { // 考试
                    if (tokens.length == 5 && tokens[3].matches("^(-?\\d+)(.\\d+|\\d+)?$")
                            && tokens[4].matches("^(-?\\d+)(.\\d+|\\d+)?$")) { // 权重值为实数
                        float weight1 = Float.parseFloat(tokens[3]);
                        float weight2 = Float.parseFloat(tokens[4]);
                        if (weight1 + weight2 > 0.99 && weight1 + weight2 < 1.01) { // 权重和为1
                            if (curriculum.findCourseByName(courseName) == null) {
                                curriculum.addCourse(new Course(courseName, description, type));
                                curriculum.findCourseByName(courseName).addWeight(weight1);
                                curriculum.findCourseByName(courseName).addWeight(weight2);
                            }
                        } else {
                            StringBuilder sb = new StringBuilder();
                            sb.append(courseName).append(" : weight value error");
                            System.out.println(sb);
                        }
                    } else {
                        System.out.println("wrong format");
                    }
                } else if (description.equals("选修") && type.matches("考试|考察")) { // 选修
                    if (type.equals("考试")) {
                        if (tokens.length == 5 && tokens[3].matches("^(-?\\d+)(\\.\\d+|\\d+)?$")
                                && tokens[4].matches("^(-?\\d+)(\\.\\d+|\\d+)?$")) { // 权重值为实数
                            float weight1 = Float.parseFloat(tokens[3]);
                            float weight2 = Float.parseFloat(tokens[4]);
                            if (weight1 + weight2 > 0.99 && weight1 + weight2 < 1.01) { // 权重和为1
                                if (curriculum.findCourseByName(courseName) == null) {
                                    curriculum.addCourse(new Course(courseName, description, type));
                                    curriculum.findCourseByName(courseName).addWeight(weight1);
                                    curriculum.findCourseByName(courseName).addWeight(weight2);
                                }
                            } else {
                                StringBuilder sb = new StringBuilder();
                                sb.append(courseName).append(" : weight value error");
                                System.out.println(sb);
                            }
                        } else {
                            System.out.println("wrong format");
                        }
                    } else if (type.equals("考察")) {
                        if (curriculum.findCourseByName(courseName) == null) {
                            curriculum.addCourse(new Course(courseName, description, type));
                        }
                    }
                } else if (description.equals("实验") && type.equals("实验")) { // 实验
                    if (tokens[3].matches("[4-9]")) {
                        boolean flag = true;
                        float weightSum = 0;
                        int length = tokens.length;
                        if (length - 4 == Integer.parseInt(tokens[3])) { // 数量==个数
                            for (int i = 4; i < length; i++) {
                                if (tokens[i].matches("^(-?\\d+)(.\\d+|\\d+)?$")) { // 权重值是实数
                                    weightSum += Float.parseFloat(tokens[i]);
                                } else {
                                    flag = false;
                                    break;
                                }
                            }
                            if (flag) {
                                if (weightSum > 0.99 && weightSum < 1.01) { // 权重和为1
                                    if (curriculum.findCourseByName(courseName) == null) {
                                        curriculum.addCourse(new Course(courseName, description, type));
                                        for (int i = 4; i < length; i++) {
                                            curriculum.findCourseByName(courseName)
                                                    .addWeight(Float.parseFloat(tokens[i]));
                                        }
                                    }
                                } else {
                                    StringBuilder sb = new StringBuilder();
                                    sb.append(courseName).append(" : weight value error");
                                    System.out.println(sb);
                                }
                            } else {
                                System.out.println("wrong format");
                            }
                        } else {
                            StringBuilder sb = new StringBuilder();
                            sb.append(courseName).append(" : number of scores does not match");
                            System.out.println(sb);
                        }
                    } else {
                        System.out.println("wrong format");
                    }
                } else {
                    StringBuilder sb = new StringBuilder();
                    sb.append(courseName).append(" : course type & access mode mismatch");
                    System.out.println(sb);
                }
            } else if (input
                    .matches(
                            "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}.*?")) { // 成绩信息
                String studentId = tokens[0];
                String classId = studentId.substring(0, 6);
                String studentName = tokens[1];
                String courseName = tokens[2];
                if (input.matches(
                        "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s([0-9]|[1-9][0-9]|100)\\s([0-9]|[1-9][0-9]|100)")) { // 考试
                    int grade = 0;
                    int performance = 0;

                    if (school.findClass_ByID(classId) == null) {
                        school.addClass(new Class_(classId));
                    }
                    if (school.findClass_ByID(classId).findStudentByName(studentName) == null) {
                        school.findClass_ByID(classId)
                                .addStudent(new Student(studentId, studentName, 0, 0));
                    }

                    if (curriculum.findCourseByName(courseName) != null) {
                        if (curriculum.findCourseByName(courseName).getExamType().equals("考试")) {
                            grade = Integer.parseInt(tokens[4]);
                            performance = Integer.parseInt(tokens[3]);
                        } else {
                            grade--;
                            StringBuilder sb = new StringBuilder();
                            sb.append(studentId).append(" ").append(studentName).append(" ")
                                    .append(": access mode mismatch");
                            System.out.println(sb);
                        }
                    } else {
                        grade--;
                        StringBuilder sb = new StringBuilder();
                        sb.append(courseName).append(" does not exist");
                        System.out.println(sb);
                    }

                    if (theSystem.hasSame(studentId, studentName, courseName) == null && grade >= 0) {
                        ArrayList<Float> d = curriculum.findCourseByName(courseName).getWeight();
                        school.findClass_ByID(classId).findStudentByName(studentName)
                                .addTotalScore((int) (performance * d.get(0) + grade * d.get(1)));
                        theSystem.addSelectCourse(
                                new SelectCourse(curriculum.findCourseByName(courseName),
                                        new ExamScore((int) (performance * d.get(0) + grade * d.get(1))),
                                        school.findClass_ByID(classId).findStudentByName(studentName)));
                    }
                } else if (input.matches(
                        "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s([0-9]|[1-9][0-9]|100)")) { // 考察
                    int grade = 0;

                    if (school.findClass_ByID(classId) == null) {
                        school.addClass(new Class_(classId));
                    }
                    if (school.findClass_ByID(classId).findStudentByName(studentName) == null) {
                        school.findClass_ByID(classId)
                                .addStudent(new Student(studentId, studentName, 0, 0));
                    }

                    if (curriculum.findCourseByName(courseName) != null) {
                        if (curriculum.findCourseByName(courseName).getExamType().equals("考察")) {
                            grade = Integer.parseInt(tokens[3]);
                        } else {
                            grade--;
                            StringBuilder sb = new StringBuilder();
                            sb.append(studentId).append(" ").append(studentName).append(" ")
                                    .append(": access mode mismatch");
                            System.out.println(sb);
                        }
                    } else {
                        grade--;
                        StringBuilder sb = new StringBuilder();
                        sb.append(courseName).append(" does not exist");
                        System.out.println(sb);
                    }

                    if (theSystem.hasSame(studentId, studentName, courseName) == null && grade >= 0) {
                        school.findClass_ByID(classId).findStudentByName(studentName)
                                .addTotalScore(grade);
                        theSystem.addSelectCourse(
                                new SelectCourse(curriculum.findCourseByName(courseName),
                                        new TestScore(grade),
                                        school.findClass_ByID(classId).findStudentByName(studentName)));
                    }
                } else if (input.matches(
                        "[1-9][0-9]{7}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}(\\s[0-9]+)+")) { // 实验
                    int cnt = 0;
                    boolean hasWrong = false;
                    float grade = 0;

                    if (school.findClass_ByID(classId) == null) {
                        school.addClass(new Class_(classId));
                    }
                    if (school.findClass_ByID(classId).findStudentByName(studentName) == null) {
                        school.findClass_ByID(classId)
                                .addStudent(new Student(studentId, studentName, 0, 0));
                    }

                    for (int i = 3; i < tokens.length; i++) {
                        if (Integer.parseInt(tokens[i]) >= 0 && Integer.parseInt(tokens[i]) <= 100) {
                            cnt++;
                        } else {
                            hasWrong = true;
                        }
                    }

                    if (!hasWrong && cnt >= 4 && cnt <= 9) {
                        if (curriculum.findCourseByName(courseName) != null) {
                            if (cnt == curriculum.findCourseByName(courseName).getCnt()) {
                                for (int i = 3; i < tokens.length; i++) {
                                    grade += Integer.parseInt(tokens[i])
                                            * curriculum.findCourseByName(courseName).getWeight().get(i - 3);
                                }
                                if (theSystem.hasSame(studentId, studentName, courseName) == null) {
                                    school.findClass_ByID(classId).findStudentByName(studentName)
                                            .addTotalScore((int) grade);
                                    theSystem.addSelectCourse(
                                            new SelectCourse(curriculum.findCourseByName(courseName),
                                                    new ExperimentScore((int) grade),
                                                    school.findClass_ByID(classId).findStudentByName(studentName)));
                                }
                            } else {
                                StringBuilder sb = new StringBuilder();
                                sb.append(studentId).append(" ").append(studentName).append(" ")
                                        .append(": access mode mismatch");
                                System.out.println(sb);
                            }
                        } else {
                            StringBuilder sb = new StringBuilder();
                            sb.append(courseName).append(" does not exist");
                            System.out.println(sb);
                        }
                    } else {
                        for (int i = 4; i < tokens.length; i++) {
                            if (Integer.parseInt(tokens[i]) < 0 || Integer.parseInt(tokens[i]) > 100) {
                                System.out.println("wrong format");
                            }
                        }
                    }
                }
            } else {
                System.out.println("wrong format");
            }
        }
        scanner.close();
        school.showStudents();
        theSystem.showCourses(curriculum);
        school.showClass_es();
    }
}

class School {
    private ArrayList<Class_> class_es = new ArrayList<>();

    public School() {

    }

    public void addClass(Class_ class_) {
        this.class_es.add(class_);
    }

    public Class_ findClass_ByID(String classId) {
        if (class_es.size() == 0) {
            return null;
        }
        for (Class_ class_ : class_es) {
            if (class_.getClassId().equals(classId)) {
                return class_;
            }
        }
        return null;
    }

    public void showClass_es() {
        Collections.sort(class_es);
        for (Class_ c : class_es) {
            StringBuilder sb = new StringBuilder();
            sb.append(c.getClassId());
            if (c.getNum() == 0) {
                sb.append(" has no grades yet");
            } else {
                sb.append(" ").append(c.getAverageScore());
            }
            System.out.println(sb);
        }
    }

    public void showStudents() {
        Collections.sort(class_es);
        for (Class_ class_ : class_es) {
            class_.showStudents();
        }
    }
}

class Class_ implements Comparable<Class_> {
    private ArrayList<Student> students = new ArrayList<>();

    private String classId;

    public Class_() {

    }

    public Class_(String classId) {
        this.classId = classId;
    }

    public String getClassId() {
        return classId;
    }

    public void setClass(String classId) {
        this.classId = classId;
    }

    public void addStudent(Student student) {
        this.students.add(student);
    }

    public int getNum() {
        int num = 0;
        for (Student student : students) {
            num += student.getCnt();
        }
        return num;
    }

    public Student findStudentByName(String s) {
        if (students.size() == 0) {
            return null;
        }
        for (Student student : students) {
            if (student.getName().equals(s)) {
                return student;
            }
        }
        return null;
    }

    public int getAverageScore() { // 计算班级平均分
        int totalScore = 0;
        int cnt = 0;
        for (Student student : students) {
            if (student.getCnt() != 0) {
                cnt += student.getCnt();
                totalScore += student.getTotalScore();
            }
        }
        return totalScore / cnt;
    }

    public void showStudents() {
        Collections.sort(students);
        for (Student s : students) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getId()).append(" ").append(s.getName());
            if (s.getCnt() == 0) {
                sb.append(" did not take any exams");
            } else {
                sb.append(" ").append(s.getAverageScore());
            }
            System.out.println(sb);
        }
    }

    @Override
    public int compareTo(Class_ o) {
        return this.getClassId().compareToIgnoreCase(o.getClassId());
    }
}

class Student implements Comparable<Student> {
    private String id;
    private String name;
    private int totalScore;
    private int cnt;

    public Student() {

    }

    public Student(String id, String name, int totalScore, int cnt) {
        this.id = id;
        this.name = name;
        this.totalScore = totalScore;
        this.cnt = cnt;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getTotalScore() {
        return totalScore;
    }

    public void setTotalScore(int totalScore) {
        this.totalScore = totalScore;
    }

    public int getCnt() {
        return cnt;
    }

    public void setCnt(int cnt) {
        this.cnt = cnt;
    }

    public void addTotalScore(int score) {
        cnt++;
        totalScore += score;
    }

    public int getAverageScore() {
        return totalScore / cnt;
    }

    @Override
    public int compareTo(Student o) {
        return this.getId().compareToIgnoreCase(o.getId());
    }
}

class Curriculum {
    private ArrayList<Course> courses = new ArrayList<>();

    public Curriculum() {

    }

    public void addCourse(Course course) {
        courses.add(course);
    }

    public Course findCourseByName(String name) {
        if (courses.isEmpty()) {
            return null;
        }
        for (Course course : courses) {
            if (course.getName().equals(name)) {
                return course;
            }
        }
        return null;
    }

    public ArrayList<Course> getCourses() {
        Collections.sort(courses);
        return courses;
    }
}

class Course implements Comparable<Course> {
    private String name;
    private String description;
    private String examType;
    private ArrayList<Float> weight = new ArrayList<>();

    public Course() {

    }

    public Course(String name, String description, String examType) {
        this.name = name;
        this.description = description;
        this.examType = examType;
    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getExamType() {
        return examType;
    }

    public void setExamType(String type) {
        this.examType = type;
    }

    public ArrayList<Float> getWeight() {
        return weight;
    }

    public void addWeight(float weight) {
        this.weight.add(weight);
    }

    public int getCnt() {
        return this.weight.size();
    }

    @Override
    public int compareTo(Course o) {
        Collator instance = Collator.getInstance(Locale.CHINA);
        return instance.compare(this.name, o.getName());
    }
}

abstract class Score {
    private int grade;

    public Score() {

    }

    public Score(int grade) {
        this.grade = grade;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int score) {
        this.grade = score;
    }
}

class ExamScore extends Score {
    public ExamScore() {
        super();
    }

    public ExamScore(int grade) {
        super(grade);
    }
}

class TestScore extends Score {
    public TestScore() {
        super();
    }

    public TestScore(int grade) {
        super(grade);
    }
}

class ExperimentScore extends Score {

    public ExperimentScore() {
        super();
    }

    public ExperimentScore(int grade) {
        super(grade);
    }
}

class TheSystem {
    private HashSet<SelectCourse> selectCourses = new HashSet<>();

    public TheSystem() {

    }

    public void addSelectCourse(SelectCourse s) {
        this.selectCourses.add(s);
    }

    public SelectCourse hasSame(String id, String stu, String cou) {
        if (selectCourses.isEmpty()) {
            return null;
        }
        for (SelectCourse s : selectCourses) {
            if (s.getStudent().getId().equals(id)
                    && s.getStudent().getName().equals(stu)
                    && s.getCourse().getName().equals(cou)) {
                return s;
            }
        }
        return null;
    }

    public void showCourses(Curriculum curr) {
        ArrayList<Course> courses = curr.getCourses();
        for (Course course : courses) {
            StringBuilder sb = new StringBuilder();
            sb.append(course.getName()).append(" ");
            int grade = 0;
            int cnt = 0;
            for (SelectCourse selectCourse : selectCourses) {
                if (selectCourse.getCourse().equals(course)) {
                    cnt++;
                    grade += selectCourse.getScore().getGrade();
                }
            }
            if (cnt == 0) {
                sb.append("has no grades yet");
            } else {
                sb.append(grade / cnt);
            }
            System.out.println(sb);
        }
    }
}

class SelectCourse implements Comparable<SelectCourse> {
    private Course course;
    private Score score;
    private Student student;

    public SelectCourse() {

    }

    public SelectCourse(Course course, Score score, Student student) {
        this.course = course;
        this.score = score;
        this.student = student;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public Score getScore() {
        return score;
    }

    public void setScore(Score score) {
        this.score = score;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public int compareTo(SelectCourse o) {
        return this.getStudent().getId().compareTo(o.getStudent().getId());
    }
}

继承和组合关系的区别

  • 继承:父类的内部细节对子类可见,其代码属于白盒式的复用,继承在编码过程中就要指定具体的父类,其关系在编译期就确定,继承强调的是is-a的关。
  • 组合:对象之间的内部细节不可见,其代码属于黑盒式复用,组合的关系一般在运行时确定,组合强调的是has-a的关系。

思考一下哪一种关系运用上更灵活,更能够适应变更
我认为组合关系在运用上更灵活,更能适应变更。
在考试、考察、实验这三种考试性质中,计算期末总成绩的方式各不相同。其中考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,考察的总成绩直接等于期末成绩,实验的总成绩等于课程每次实验成绩乘以权重后累加而得。
所以在计算期末总成绩时,getFinalScore()方法中的计算方式各不相同,而且考试成绩、考察成绩、实验成绩中所含有的属性也不一致。
因此我认为组合关系在运用上更灵活,更能适应变更。

踩坑心得

OOP训练集09 7-1 统计Java程序中关键词的出现次数
踩坑与心得

一开始在去掉相应的注释中内容后,直接这样替换非字母的内容为空格,样例倒是能过,但是最后得到的结果却是这样的

之后根据他这上面写的测试样例描述,来替换内容

但是仍旧存在错误

最后在调试的过程中,发现仅通过一个空格将字符串分隔开,会出现空字符串的情况

之后将其改成

就通过了所有的测试

代码行数为54,成功达到一档
源码如下:

import java.util.*;
import java.util.Map.Entry;

public class Main {
    public static void main(String[] args) {
        String[] splitStr = input();

        output(splitStr);
    }

    private static String[] input() {
        Scanner scanner = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        boolean hasInput = false;
        while (true) {
            String s = scanner.nextLine();
            if (s.equalsIgnoreCase("exit"))
                break;
            sb.append(s.replaceAll("//(.*)", "").replaceAll("\"(.*?)\"", " ")).append(" "); // //注释 "字符串"
            hasInput = true;
        }
        scanner.close();

        hasInput(hasInput);
        String str = sb.toString();
        str = str.replaceAll("/\\*(.*?)\\*/", " ").replaceAll("/\\*\\*(.*?)\\*/", " ")
                .replaceAll("\\s+|\\(|\\)|\\{|}|\\.|;|,|\\[|\\]", " ");
        return str.split("\\s+");
    }

    private static void output(String[] splitStr) {
        Set<String> words = new HashSet<>(Arrays.asList(new String[] { "new", "assert", "boolean", "break", "byte",
                "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum",
                "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof",
                "int", "interface", "long", "native", "abstract", "null", "package", "private", "protected", "public",
                "return", "strictfp", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws",
                "transient", "try", "void", "volatile", "while", "true", "false" }));
        TreeMap<String, Integer> keyWords = new TreeMap<String, Integer>();
        for (String s : splitStr) // 判断关键字并保存出现次数
            if (keyWords.containsKey(s))
                keyWords.put(s, keyWords.get(s) + 1);
            else if (words.contains(s))
                keyWords.put(s, 1);
        Set<Entry<String, Integer>> entries = keyWords.entrySet();
        entries.forEach(e -> System.out.println(e.getValue() + "\t" + e.getKey()));
    }

    private static void hasInput(boolean hasInput) {
        if (!hasInput) {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }
}

其实在最短的时候,代码长度是33行,只是程序没有模块化,可读性差

import java.util.*;
import java.util.Map.Entry;
public class Main {
    public static void main(String[] args) {
        Set<String> words = new HashSet<>(Arrays.asList(new String[] { "new", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "abstract", "null", "package", "private", "protected", "public", "return", "strictfp", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while", "true", "false" }));
        TreeMap<String, Integer> keyWords = new TreeMap<String, Integer>();
        Scanner scanner = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        boolean hasInput = false;
        while (true) {
            String s = scanner.nextLine();
            if (s.equalsIgnoreCase("exit"))
                break;
            sb.append(s.replaceAll("//(.*)", "").replaceAll("\"(.*?)\"", " ")).append(" "); // //注释 "字符串"
            hasInput = true;
        }
        scanner.close();
        if (!hasInput) {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        String str = sb.toString();
        str = str.replaceAll("/\\*(.*?)\\*/", " ").replaceAll("/\\*\\*(.*?)\\*/", " ").replaceAll("\\s+|\\(|\\)|\\{|}|\\.|;|,|\\[|\\]", " ");
        String[] splitStr = str.split("\\s+");
        for (String s : splitStr) // 判断关键字并保存出现次数
            if (keyWords.containsKey(s))
                keyWords.put(s, keyWords.get(s) + 1);
            else if (words.contains(s))
                keyWords.put(s, 1);
        Set<Entry<String, Integer>> entries = keyWords.entrySet();
        entries.forEach(e -> System.out.println(e.getValue() + "\t" + e.getKey()));
    }
}

改进建议

  • 在进行代码复用时,考虑使用继承还是组合关系,如果类之间的继承结构稳定(不会轻易改变),继承层次比较浅(比如,最多有两层继承关系),继承关系不复杂,就可以考虑使用继承。反之,系统越不稳定,继承层次很深,继承关系复杂,就尽量使用组合来替代继承。
  • 写程序时要模块化,比如在OOP训练集09 7-1 统计Java程序中关键词的出现次数中,33行没有模块化的代码,相较于54行模块化后的代码,可读性确实较差。
  • 需要学习在Java中数学运算时,不同计算方式对程序产生的误差,学习用何种方式做数学运算产生的误差更小,结果更接近实际。

总结

  • 总的来说,本阶段学到了Hashset、HashMap、TreeMap的使用方法,以及HashMap的排序,也学到了一些新的正则表达式的使用,对正则表达式的使用更加熟练。
  • 关于建议:
    • PTA到了截止时间后,可以给一些讲解,就比如OOP训练集11 7-2 课程成绩统计程序-3,case14这个测试点错误原因。
    • Java学习初期,可以提前说跟同学说上课不讲Java语法,需要自学,不然在Java初期,学的手忙脚乱,毫无头绪,而且同时还需要学习设计原则,此时几乎没学明白,到了后面才慢慢适应过来。
    • 后期让同学讲JavaFX十分缓慢,JavaFX比较简单,这段的学习可以稍快,而设计原则这类比较难的知识可以多些时间让同学学习、消化。