Java第三次PTA作业总结

一、前言

开头废话:

最后一次题目集,可以说是这段日子里对Java学习的总结,在这几个题目集中的没有很多关于算法的考察,而是更加强调其中代码设计,无论是菜单,还是成绩统计的迭代,也都不难看出代码设计的重要性,好的设计,符合面向对象的设计可在代码迭代中省时省力。之前的菜单还没怎么体会(因为我的完成度不高),但是在成绩统计中真的是深有体会,类的设计做好的话,一次迭代只需要改几个小时后提交就可以获得大量测试点通过后的感觉还是很爽,但要是没设计好,迭代一次也真的是跑断腿,随着新功能的加入,基本每个地方都需要修改就很头疼。

题目集分析:

OOP训练集07:

一道菜单迭代题(菜单-5),也是菜单的最后一次迭代,这次菜单题是在菜单3的基础上迭代,不是菜单4的迭代,菜单5没有菜单4那么多异常情况,而是加入口味度,口味度这个功能要求是很多的,比如口味度平均值的计算,对于我来说难度确实不小。

OOP训练集08:

一道成绩统计题(成绩统计-1),是新的系列,也是成绩统计的第一版本,其实总体跟菜单差不多,但是这一次其实更加注重类的设计,强调要用继承,相比于之前迭代的菜单,其实设计也不算复杂,难度还行

OOP训练集09:

一道统计关键词题,这次题目集属于额外内容,主要要求我们必须使用set,map和正则表达式进行Java中关键词出现次数统计,而且老师强调需要代码大小有要求,且必须使用面向对象设计,一方面要考虑测试点通过,另一方面要对代码结构进行精简,如果想尝试代码精简很多的话难度确实也不小。

OOP训练集10:

一道成绩统计迭代题(成绩统计-2),还有三道其他题目(考察HashMap和多态)难度可以说是送分的,成绩统计的第一次迭代加入了实验课的统计功能,增加的功能其实也不算多,难度不高。

OOP训练集11:

一道成绩统计迭代题(成绩统计-3),还有四道其他题目(考察排序,自定义接口和覆盖)也可以说是送分题,成绩统计的第二次迭代修改了课程计算总成绩的方式(分项成绩的权重计算总成绩),且要求修改类设计结构,将原本的继承改为组合,修改的地方比较多,难度较高。

二、设计与分析

菜单计价程序-5:

源代码

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        @SuppressWarnings("resource")
        Scanner in = new Scanner(System.in);
        Dish[] dish = new Dish[10];
        ArrayList<String> customs = new ArrayList<String>();
        String[] command = in.nextLine().split(" ");
        for(int i = 0; !command[0].equals("table"); i++) {
            if(command.length > 2) {
                if(command.length == 4) {
                    if(command[3].equals("T")) {
                        dish[i] = new Dish(command[0],Integer.parseInt(command[2]),true);
                        dish[i].setTaste(command[1]);
                    }
                }
                else {
                    System.out.println("wrong format");
                    dish[i] = new Dish();
                }        
            }
            else 
                dish[i] = new Dish(command[0],Integer.parseInt(command[1]),false);
            if(!(dish[i].getUtilPrice() >= 0&&dish[i].getUtilPrice() < 300)) {
                System.out.println(dish[i].getName()+" price out of range "+dish[i].getUtilPrice());
                dish[i] = new Dish();
            }
            command = in.nextLine().split(" ");
        }
        Menu menu = new Menu(dish);
        if(command[0].equals("table")) {
            Custom[] custom = new Custom[10];
            int customNum = 0;
            Table[] table = new Table[10];
            int tableNum = 0;
            for(tableNum = 0; command[0].equals("table"); tableNum++) {
                custom[customNum] = new Custom(command[3],command[4]);
                table[tableNum] = new Table(Integer.parseInt(command[1]),command[3],custom[customNum].getPhone(),command[5],command[6]);                
                if(!custom[customNum].getPhone().equals("error")&&custom[customNum].getName().length() <= 10) {
                    if(table[tableNum].isOpeningHours()) {
                        System.out.println("table "+table[tableNum].getNum()+": ");
                        if(!customs.contains(custom[customNum].getName()))
                            customs.add(custom[customNum].getName());
                    }
                }
                else
                    System.out.println("wrong format");
                Record[] records = new Record[10];
                command = in.nextLine().split(" ");
                for(int j = 0; !(command[1].equals("delete")||command[0].equals("table")); j++) {
                    if(table[tableNum].getPhone().equals("error")) {
                        command = in.nextLine().split(" ");
                        if(command[0].equals("end"))
                            break;
                        continue;
                    }
                    if(command[0].length() > 2) {
                        if(command.length > 3)
                            records[j] = new Record(1,new Dish(),0,0,0);
                        else
                            System.out.println("invalid dish");
                    }
                    else {
                        if(menu.searthDish(command[1]).getName().equals("notexist")) {
                            System.out.println(command[1]+" does not exist");
                            records[j] = new Record();
                        }
                        else {
                            if(command.length > 4)//特色菜
                                records[j] = new Record(Integer.parseInt(command[0]),menu.searthDish(command[1]),Integer.parseInt(command[2]),Integer.parseInt(command[3]),Integer.parseInt(command[4]));
                            else//非特色菜
                                records[j] = new Record(Integer.parseInt(command[0]),menu.searthDish(command[1]),0,Integer.parseInt(command[2]),Integer.parseInt(command[3]));
                        }
                    }
                    command = in.nextLine().split(" ");
                    if(command[0].equals("end"))
                        break;
                }
                Order order = new Order(records,menu);
                table[tableNum].setOrder(order);
                if(!table[tableNum].getPhone().equals("error")&&table[tableNum].isOpeningHours())
                    order.showOrder();
                if(!command[0].equals("end")) {
                    while(command[1].equals("delete")) {
                        order.delARecordByOrderNum(Integer.parseInt(command[0]));
                        command = in.nextLine().split(" ");
                        if(command[0].equals("end"))
                            break;
                    }
                }
            }
            for(int i = 0; i < tableNum; i++) {
                if(!table[i].getPhone().equals("error"))
                    table[i].showTotal();
            }
            Collections.sort(customs, new Comparator<String>(){
                    public int compare(String o1, String o2) {
                        return o1.compareToIgnoreCase(o2);
                    }
                }
            );
            for(int i = 0; i < customs.size(); i++) {
                int total = 0;
                String phone = "";
                for(int j = 0; j < tableNum; j++) {
                    if(table[j].getName().equals(customs.get(i))&&!table[j].getPhone().equals("error")) {
                        total += table[j].getDiscountedPrice();
                        phone = table[j].getPhone();
                    }
                }
                System.out.println(customs.get(i)+" "+phone+" "+total);
            }
        }
        else
            System.out.println("wrong format");
    }
}
class Dish{
    private String name;
    private int util_price;
    private boolean t;
    private String taste;
    
    public Dish() {
        name = "";
        util_price = 0;
        t = false;
    }
    public Dish(String name,int util_price,boolean t){
        this.name = name;
        this.util_price = util_price;
        this.t = t;
    }
    public String getName() {
        return name;
    }
    public int getUtilPrice() {
        return util_price;
    }
    public boolean getT() {
        return t;
    }
    public String getTaste() {
        return taste;
    }
    public void setTaste(String taste) {
        this.taste = taste;
    }
    public int getPrice(int portion){
        double price = 0;
        switch(portion){
            case 1:{
                price = util_price;
                break;
            }
            case 2:{
                price = util_price * 1.5;
                break;
            }
            case 3:{
                price = util_price * 2;
                break;
            }
        }
        if(price - (int)price >= 0.5) 
            return (int)price + 1;
        else
            return (int)price;
    }
}

class Menu{
    private Dish[] dishs;
    
    public Menu(Dish[] dishs) {
        this.dishs = new Dish[dishs.length];
        for(int i = 0; i < dishs.length; i++) {
            if(dishs[i] == null)
                this.dishs[i] = new Dish();
            else
                this.dishs[i] = dishs[i];
        }
    }
    public Dish searthDish(String dishName) {
        int num = 0;
        Dish flag = new Dish("notexist",0,false); 
        for(int i = 0; i < dishs.length; i++) {
            if(dishs[i].getName().equals(dishName)) {
                num = i;
                flag = new Dish("exist",0,false); 
            }        
        }
        if(flag.getName().equals("exist"))
            return dishs[num];
        else
            return flag;
    }
    public Dish addDish(String dishName,int unit_price,boolean t) {
        return new Dish(dishName,unit_price,t);
    }
}
 class Record{
     private int orderNum;
     private Dish d;
     private int taste;//口味度
     private int portion;
     private int num;
     
     public Record() {
         orderNum = 0;
         d = new Dish();
         taste = 0;
         portion = 0;
         num = 0;
     }
     public Record(int orderNum,Dish d,int taste,int portion,int num) {
         this.orderNum = orderNum;
         this.d = d;
         this.taste = taste;
         this.portion = portion;
         this.num = num;
     }
     public int getOrderNum(){
         return orderNum;
     }
     public Dish getDish() {
         return d;
     }
     public int getPortion() {
         return portion;
     }
     public int getNum() {
         return num;
     }
     public int getTaste() {
        return taste;
    }
    public void setTaste(int taste) {
        this.taste = taste;
    }
    public int getPrice() {
         if(isTaste(taste,d).equals("yes")) {
             if(!d.getT()&&(portion < 0||portion > 3))
                 return 0;
             else if(d.getT()&&(portion < 0||portion > 3))
                 return 0;
             else {
                if(num > 15)
                     return 0;
                 else
                     return d.getPrice(portion)*num;
             }
         }
         else
             return 0;
         
     }
     public String isTaste(int taste,Dish d) {
         if(d.getT()) {
             if(d.getTaste().equals("川菜")) {
                 if(taste >= 0&&taste <= 5)
                     return "yes";
                 else
                     return "spicy";
             }     
             else if(d.getTaste().equals("晋菜")) {
                 if(taste >= 0&&taste <= 4)
                     return "yes";
                 else
                     return "acidity";
             }         
             else if(d.getTaste().equals("浙菜")) {
                 if(taste >= 0&&taste <= 4)
                     return "yes";
                 else
                     return "sweetness";
             }
             else
                 return "yes";
         }
         else
             return "yes";
     }
     public void Priceshow() {
         if(portion < 10) {
             if(!d.getT()&&(portion < 0||portion > 3))
                 System.out.println(orderNum+" num out of range "+portion);
             else if(d.getT()&&(portion < 0||portion > 3))
                 System.out.println(orderNum+" portion out of range "+portion);
             else if(!isTaste(taste,d).equals("yes")) {
                 System.out.println(isTaste(taste,d)+" num out of range :"+taste);
                 taste = 0;
                 num = 0;
             }
             else {
                 if(num > 15)
                     System.out.println(orderNum+" num out of range "+num);
                 else
                     System.out.println(orderNum+" "+d.getName()+" "+getPrice());
             }
         }
         else
             System.out.println("wrong format");
     }
 }

class Order{
    private Record[] records;
    private Menu menu;
    private int[] taste = new int[3];
    private int[] tasteNum = new int[3];
    
    public Order(Record[] records,Menu menu) {
        this.records = new Record[records.length];
        for(int i = 0; i < records.length; i++)
            if(records[i] == null)
                this.records[i] = new Record();
            else
                this.records[i] = records[i];
        this.menu = menu;
        for(int i = 0; i < 3; i++) {
            taste[i] = 0;
            tasteNum[i] = 0;
        }
    }
    public Record[] getRecords() {
        return records;
    }
    public int[] getTaste() {
        return taste;
    }
    public void setTaste(int[] taste) {
        this.taste = taste;
    }
    public int[] getTasteNum() {
        return tasteNum;
    }
    public void setTasteNum(int[] tasteNum) {
        this.tasteNum = tasteNum;
    }
    public int getTotalPrice() {
        int TotalPrice = 0;
        for(int i = 0; i < records.length; i++) {
            TotalPrice += records[i].getPrice();
        }
        return TotalPrice;
    }
    public Record addARecord(int orderNum,String dishName,int portion,int num) {
        Dish d = menu.searthDish(dishName);
        Record error = new Record();
        if(d.getName().equals(""))
            return error;
        else
            return new Record(orderNum,d,0,portion,num);
    }
    public void delARecordByOrderNum(int orderNum) {
        int flag = findRecordByNum(orderNum);
        if(flag != -1) {
            if(records[flag].getNum() == 0)
                System.out.println("deduplication "+ orderNum);
            records[flag] = new Record(orderNum,new Dish(),0,0,0);
        }
        else
            System.out.println("delete error");
    }
    public int findRecordByNum(int orderNum) {
        for(int i = 0; i < records.length; i++) {
            if(records[i].getOrderNum() == orderNum) {
                return i;
            }
        }
        return -1;
    }
    public void averageTaste() {
        double[] totalTaste = new double[3];
        for(int i = 0; i < 3; i++) {
            totalTaste[i] = 0;
        }
        for(int i = 0; i < records.length; i++ ) {
            if(records[i].getDish().getT()) {
                if(records[i].getDish().getTaste().equals("川菜")) {
                    totalTaste[0] += records[i].getTaste()*records[i].getNum();
                    tasteNum[0] += records[i].getNum();
                }
                else if(records[i].getDish().getTaste().equals("晋菜")) {
                    totalTaste[1] += records[i].getTaste()*records[i].getNum();
                    tasteNum[1] += records[i].getNum();
                }
                else if(records[i].getDish().getTaste().equals("浙菜")) {
                    totalTaste[2] += records[i].getTaste()*records[i].getNum();
                    tasteNum[2] += records[i].getNum();
                }
            }
        }
        for(int i = 0; i < 3; i++) {
            totalTaste[i] = totalTaste[i] / tasteNum[i];
            if(totalTaste[i] - (int)totalTaste[i] >= 0.5) 
                taste[i] = (int)totalTaste[i] + 1;
            else
                taste[i] = (int)totalTaste[i];
        }
    }
    public void showOrder() {//展示每条记录的价格
        for(int i = 0; i < records.length; i++) {
            if(records[i].getNum() != 0) {
//                int m = i;
//                for(m = i; m > 0; m--) {
//                    if(records[m-1].getOrderNum() >= records[i].getOrderNum()) {
//                        System.out.println("record serial number sequence error");
//                        records[i] = new Record();
//                        break;
//                    }
//                }
//                if(m == 0)
                    records[i].Priceshow();
            }
            else {
                if(records[i].getOrderNum() == 1) 
                    System.out.println("wrong format");
            }
        }
    } 
}
class Table {
    private int num;
    private Order order;
    private String name;
    private String phone;
    private LocalDate date;
    private LocalTime time;
    private double total;
    
    public Table(int num, String name, String phone, String date, String time) {
        this.num = num;
        this.name = name;
        this.phone = phone;
        if(check(date)) {
            String[] DATE = date.split("/");
            this.date = LocalDate.of(Integer.parseInt(DATE[0]),Integer.parseInt(DATE[1]),Integer.parseInt(DATE[2]));
        }
        else
            this.date = LocalDate.of(1,1,1);
        String[] TIME = time.split("/");
        this.time = LocalTime.of(Integer.parseInt(TIME[0]),Integer.parseInt(TIME[1]),Integer.parseInt(TIME[2]));
        this.total = 0.0;
    }
    public void setOrder(Order order) {
        this.order = order;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public int getNum() {
        return num;
    }
    public Order getOrder() {
        return order;
    }
    public LocalDate getDate() {
        return date;
    }
    public LocalTime getTime() {
        return time;
    }
    public double getTotal() {
        return total;
    }
    public int getWeek() {
        return date.get(ChronoField.DAY_OF_WEEK);
    }
    public boolean isOpeningHours() {
        int week = getWeek();
        if(week <= 5) {
            if(time.isAfter(LocalTime.of(16,59,59))&&time.isBefore(LocalTime.of(20,30,1)))
                return true;
            else if(time.isAfter(LocalTime.of(10,29,59))&&time.isBefore(LocalTime.of(14,30,1)))
                return true;
            else
                return false;    
        }
        else {
            if(time.isAfter(LocalTime.of(9,29,59))&&time.isBefore(LocalTime.of(21,30,1)))
                return true;
            else
                return false;
        }
    }
    public int OpeningHours(int week,LocalTime time,boolean T) {
        if(week <= 5) {
            if(T) {
                return 7;
            }
            else {
                if(time.isAfter(LocalTime.of(16,59,59))&&time.isBefore(LocalTime.of(20,30,1)))
                    return 8;
                else if(time.isAfter(LocalTime.of(10,29,59))&&time.isBefore(LocalTime.of(14,30,1)))
                    return 6;
                else
                    return -1;
            }
            
        }
        else {
            if(time.isAfter(LocalTime.of(9,29,59))&&time.isBefore(LocalTime.of(21,30,1)))
                return 10;
            else
                return -1;
        }
    }
    public int getDiscountedPrice() {
        int discountedPrice = 0;
        Record[] records = order.getRecords();
        double[] price = new double[records.length];
        for(int i = 0; i < records.length; i++) {
            price[i] = records[i].getPrice()*OpeningHours(getWeek(),getTime(),records[i].getDish().getT())*0.1;
            if(price[i] - (int)price[i] >= 0.5) 
                price[i] = (int)price[i] + 1;
            else
                price[i] = (int)price[i];
        }
        for(int i = 0; i < price.length; i++)
            discountedPrice += (int)price[i];
        return discountedPrice;
    }
    public void showTaste() {
        order.averageTaste();
        if(order.getTasteNum()[0] > 0) {//辣度
            System.out.print(" 川菜 ");
            switch(order.getTaste()[0]) {
                case 0:
                    System.out.print(order.getTasteNum()[0]+" 不辣");
                    break;
                case 1:
                    System.out.print(order.getTasteNum()[0]+" 微辣");
                    break;
                case 2:
                    System.out.print(order.getTasteNum()[0]+" 稍辣");
                    break;
                case 3:
                    System.out.print(order.getTasteNum()[0]+" 辣");
                    break;
                case 4:
                    System.out.print(order.getTasteNum()[0]+" 很辣");
                    break;
                case 5:
                    System.out.print(order.getTasteNum()[0]+" 爆辣");
                    break;
            }
        }
        if(order.getTasteNum()[1] > 0) {//辣度
            System.out.print(" 晋菜 ");
            switch(order.getTaste()[1]) {
                case 0:
                    System.out.print(order.getTasteNum()[1]+" 不酸");
                    break;
                case 1:
                    System.out.print(order.getTasteNum()[1]+" 微酸");
                    break;
                case 2:
                    System.out.print(order.getTasteNum()[1]+" 稍酸");
                    break;
                case 3:
                    System.out.print(order.getTasteNum()[1]+" 酸");
                    break;
                case 4:
                    System.out.print(order.getTasteNum()[1]+" 很酸");
                    break;
            }
        }
        if(order.getTasteNum()[2] > 0) {//辣度
            System.out.print(" 浙菜 ");
            switch(order.getTaste()[2]) {
                case 0:
                    System.out.print(order.getTasteNum()[2]+" 不甜");
                    break;
                case 1:
                    System.out.print(order.getTasteNum()[2]+" 微甜");
                    break;
                case 2:
                    System.out.print(order.getTasteNum()[2]+" 稍甜");
                    break;
                case 3:
                    System.out.print(order.getTasteNum()[2]+" 甜");
                    break;
            }
        }
    }
    public void showTotal() {
        int judge = OpeningHours(getWeek(),getTime(),false);
        if(judge == -1)
            System.out.println("table"+" "+num+" out of opening hours");
        else {
            if(date.isAfter(LocalDate.of(2020,1,1))&&date.isBefore(LocalDate.of(2023,12,31))) {
                System.out.print("table"+" "+num+": "+order.getTotalPrice()+" "+getDiscountedPrice());
                showTaste();
                System.out.println();
            }    
            else
                System.out.println("not a valid time period");
        }
    }
    public static boolean check (String str) {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy/MM/dd");
        try {
            sd.setLenient(false);
            sd.parse(str);
        }
        catch (Exception e) {
            return false;
        }
        return true;
    }
}
class Custom{
    private String name;
    private String phone;
    private int consumption;
    
    public Custom() {
        name = "";
        phone = "";
        consumption = 0;
    }
    public Custom(String name, String phone) {
        super();
        this.name = name;
        String regExp = "^(180|181|189|133|135|136)([0-9]{8}?)$";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(phone);
        if(matcher.find())
            this.phone = phone;
        else
            this.phone = "error";
        
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {        
        this.phone = phone;
    }
    public int getConsumption() {
        return consumption;
    }
    public void setConsumption(int consumption) {
        this.consumption = consumption;
    }
}

类图

设计分析

讲道理这次菜单系列的设计是比较糟糕的,首先我是用数组来储存数据的,并不是ArrayList,实际用数组的体验下来是十分糟糕,尤其是查找,在需要在代码中经常使用到,为了对各个对象查找往往需要专门写一个方法,而且这种查找方式可拓展性差,在回顾修改时给我带来了不小的麻烦,其实相比于上一次的迭代完成度还是较高的。

统计Java程序中关键词的出现次数

源代码

 

import java.util.*;
public class Main {
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        HashSet set = new HashSet<>();
        String[] keyword = {"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while"};
        for (String str : keyword)
            set.add(str);
        TreeMap<String,Integer> keywords = new TreeMap();
        SentenceSet sentenceSet = new SentenceSet();
        int flag = 0;
        String sentence = in.nextLine();
        for(; !sentence.equals("exit"); sentence = in.nextLine(), flag = 1)
            sentenceSet.sentences.add(new Sentence(sentence));
        if(flag == 0){
            System.out.println("Wrong Format");
            return;
        }
        String[] a = sentenceSet.stringSplit();
        for(int j = 0; j < a.length; j++){;
            if(set.contains(a[j])){
                if(keywords.containsKey(a[j])){
                    int num = keywords.get(a[j]) + 1;
                    keywords.put(a[j],num);
                }
                else
                    keywords.put(a[j],1);
            }
        }
        for(HashMap.Entry<String, Integer> map : keywords.entrySet())
            System.out.println(map.getValue()+"\t"+map.getKey());
//        sentenceSet.sentences.forEach(r->{
//            System.out.println(r.sentence);
//        });
    }
}
class Sentence{
    String sentence;
    public Sentence(String sentence) {
        this.sentence = sentence;
    }
}
class SentenceSet{
    LinkedHashSet<Sentence> sentences= new LinkedHashSet();
    StringBuilder sentenceAll = new StringBuilder();
    public String[] stringSplit(){
        sentences.forEach(r->sentenceAll.append(r.sentence.replaceAll("//.*", " ").replaceAll("\"(.*?)\"", " ")));
        String s = sentenceAll.toString().replaceAll("/\\*(.*?)\\*/", " ");
        return s.split("\\s+|\\{|\\}|\\.|\\,|\\[|\\]|;|\\(|\\)");
    }
}

 

 

 

设计分析

虽然这题比起其他的迭代版本来比代码量少了很多,但是短小精悍,因为需要尽可能的缩减代码量,因此运用模块化思维,将主方法中语句全部使用方法代替,能省一点是一点,Sentence类是用来储存程序代码中的每个句子,为了使用set的同时避免set的去重性,SentenceSet类是用来对代码中所有句子中符号及多空格替换成单空格,并将其每个关键词拆分成一个个数组,在最后统计关键词出现次数时用到set中的查询方法,将Java中所有关键词存入set中,方便后面对关键词进行查询统计,最后统计完数量后输出结果。

课程成绩统计程序-1

源代码

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Collections;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        GradeData gradeData = new GradeData();
        ArrayList<SelectedCourse> selectedCourses= new ArrayList<>();
        Pattern pattern = Pattern.compile("[0-9]*");
        String[] command = in.nextLine().split(" ");
        while (!command[0].equals("end") && !pattern.matcher(command[0]).matches()){
            if((command.length == 3 || command.length == 4) && command[0].length() <= 10){
                if((command[1].equals("必修")||command[1].equals("选修"))&&(command[2].equals("考试")||command[2].equals("考察"))){
                    if(!gradeData.getCourse().contains(new Course(command[0],"","")))
                        if(!gradeData.addCourse(command[0],command[1],command[2]))
                            System.out.println(command[0]+" : course type & access mode mismatch");
                }
                else
                    System.out.println("wrong format");
            }
            else
                System.out.println("wrong format");
            command = in.nextLine().split(" ");
        }
        while (!command[0].equals("end")){
            if(command.length == 5 || command.length == 4) {
                SelectedCourse record = new SelectedCourse(command);
                if (record.judge()) {
                    if (!selectedCourses.contains(record)) {
                        if (command.length == 4) {
                            int judge = gradeData.addCourseScore(command[2], -1, Integer.parseInt(command[3]));
                            if (judge == -1)
                                System.out.println(command[2] + " does not exist");
                            else if (judge == -2)
                                System.out.println(command[0] + " " + command[1] + " : access mode mismatch");
                            else if (judge == 0)
                                selectedCourses.add(record);
                            gradeData.addStudent(Integer.parseInt(command[0]), command[1], command[2], -1, Integer.parseInt(command[3]));
                            gradeData.addClass(command[0]);
                        } else {
                            int judge = gradeData.addCourseScore(command[2], Integer.parseInt(command[3]), Integer.parseInt(command[4]));
                            if (judge == -1)
                                System.out.println(command[2] + " does not exist");
                            else if (judge == -2)
                                System.out.println(command[0] + " " + command[1] + " : access mode mismatch");
                            else if (judge == 0)
                                selectedCourses.add(record);
                            gradeData.addStudent(Integer.parseInt(command[0]), command[1], command[2], Integer.parseInt(command[3]), Integer.parseInt(command[4]));
                            gradeData.addClass(command[0]);
                        }
                    }
                }
                else
                    System.out.println("wrong format");
            }
            else
                System.out.println("wrong format");
            command = in.nextLine().split(" ");
        }
        gradeData.studentSort();
        gradeData.courseSort();
        gradeData.classSort();
        gradeData.scorePrint();
    }
}
class GradeData {
    private ArrayList<Course> courses = new ArrayList<>();
    private ArrayList<Student> students = new ArrayList<>();
    private ArrayList<Class> classes = new ArrayList<>();
    private Score score = new ExamScore(0,0);

    public GradeData() {
    }
    public ArrayList<Course> getCourse() {
        return courses;
    }
    //添加课程信息
    public boolean addCourse(String course, String property, String form){
        if(course.length() > 10){
            System.out.println("wrong format");
            return true;
        }
        if(findCourse(course) >= 0)
            return true;
        if(property.equals("必修") && form.equals("考察"))
            return false;
        if(findCourse(course) == -1)
            this.courses.add(new Course(course, property, form));
        return true;
    }
    public int addCourseScore(String course, int uScore, int fScore){
        int index = findCourse(course);
        if(index == -1){
            return -1;
        }
        else{
            Course replace = courses.get(index);
            if(replace.getForm().equals("考试")){
                if(uScore >= 0){
                    score = new ExamScore(fScore,uScore);
                    replace.addFinalScore(fScore);
                    replace.addUsualScore(uScore);
                }
                else
                    return -2;
            }
            else{
                if(uScore < 0){
                    score = new ResearchSourse(fScore);
                    replace.addFinalScore(fScore);
                }
                else
                    return -2;
            }
            replace.addTotalScore(score.getTotalScore());
            courses.set(index, replace);
            return 0;
        }
    }
    public int findCourse(String course){
        Course judge = new Course(course,"","");
        return courses.indexOf(judge);
    }
    public void addStudent(int stuID, String name, String course, int uScore, int fScore){
        int index = findStudent(stuID);
        if(index == -1)
            this.students.add(new Student(name, stuID));
        if(courses.contains(new Course(course,"",""))) {
            if(!(courses.get(findCourse(course)).getForm().equals("考试") && uScore == -1)){
                if(!(courses.get(findCourse(course)).getForm().equals("考察") && uScore >= 0)){
                    if (courses.get(findCourse(course)).getForm().equals("考试"))
                        score = new ExamScore(fScore, uScore);
                    else
                        score = new ResearchSourse(fScore);
                    index = findStudent(stuID);
                    Student replace = students.get(index);
                    replace.addTotalScore(score.getTotalScore());
                    students.set(index, replace);
                }
            }
        }
    }
    public int findStudent(int stuID){
        Student judge = new Student("", stuID);
        return students.indexOf(judge);
    }
    public void addClass(String stuID){
        if(stuID.length() == 8 && findClass(stuID.substring(0,6)) == -1)
            classes.add(new Class(stuID.substring(0,6), -1));
        int index = findClass(stuID.substring(0,6));
        if(!students.get(findStudent(Integer.parseInt(stuID))).getTotalScores().isEmpty()){
            Class replace = classes.get(index);
            replace.addStudent(students.get(findStudent(Integer.parseInt(stuID))));
            classes.set(index, replace);
        }
    }
    public int findClass(String classNum){
        Class jugde = new Class(classNum, -1);
        return classes.indexOf(jugde);
    }
    public void courseSort(){
        Collections.sort(courses, new Comparator<Course>() {
            @Override
            public int compare(Course o1, Course o2) {
                Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
                Matcher m1 = p.matcher(o1.getCourse());
                Matcher m2 = p.matcher(o2.getCourse());
                if(m1.find()&&m2.find()){
                    if(o1.getCourse().compareTo(o2.getCourse()) > 0){
                        return -1;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) == 0){
                        return 0;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) < 0){
                        return 1;
                    }
                }
                else {
                    if(o1.getCourse().compareTo(o2.getCourse()) > 0){
                        return 1;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) == 0){
                        return 0;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) < 0){
                        return -1;
                    }
                }
                return 0;
            }
        });
    }
    public void studentSort(){
        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getStuID() > o2.getStuID()){
                    return 1;
                }else if(o1.getStuID() == o2.getStuID()){
                    return 0;
                }else if(o1.getStuID() < o2.getStuID()){
                    return -1;
                }
                return 0;
            }
        });
    }
    public void classSort(){
        Collections.sort(classes, new Comparator<Class>() {
            @Override
            public int compare(Class o1, Class o2) {
                if(o1.getAverageScore() > o2.getAverageScore()){
                    return -1;
                }else if(o1.getAverageScore() == o2.getAverageScore()){
                    return 0;
                }else if(o1.getAverageScore() < o2.getAverageScore()){
                    return 1;
                }
                return 0;
            }
        });
    }
    public void scorePrint(){
        for (int i = 0; i < students.size(); i++)
            students.get(i).scoreShow();
        for (int i = 0; i < courses.size(); i++)
            courses.get(i).scoreShow();
        for (int i = 0; i < classes.size(); i++)
            classes.get(i).scoreShow();
    }
}
class SelectedCourse {
    public Course course;
    public Student student;
    public String[] command;
    public SelectedCourse(String[] command) {
        this.course = new Course(command[2],"","");
        this.student = new Student("",Integer.parseInt(command[0]));
        this.command = command;
    }
    public boolean judge(){
        Pattern pattern = Pattern.compile("0|[0-9]{1,2}|100");
        if(command[0].length() == 8 && command[1].length() <= 10){
            if(pattern.matcher(command[3]).matches()){
                if(command.length == 4){
                    return true;
                }
                else if(pattern.matcher(command[4]).matches()){
                        return true;
                }
                else
                    return false;
            }
            else
                return false;
        }
        else
            return false;

    }
    public Course getCourse() {
        return course;
    }
    public Student getStudent() {
        return student;
    }
    @Override
    public boolean equals(Object obj) {
        SelectedCourse sc = (SelectedCourse) obj;
        if(this.course.getCourse().equals(sc.getCourse().getCourse())&&this.student.getStuID() == sc.getStudent().getStuID())
            return true;
        else
            return false;
    }
}
class Class {
    private String classNum;
    private int averageScore;
    private ArrayList<Student> students = new ArrayList<>();
    public Class(String classNum, int averageScore) {
        this.classNum = classNum;
        this.averageScore = averageScore;
    }
    public void addStudent(Student student){
        students.add(student);
        double score = 0.0;
        for(int i = 0; i < students.size(); i++)
                score += students.get(i).getAverageScore();
        this.averageScore = (int)(score / students.size());
    }
    public int getAverageScore() {
        return averageScore;
    }
    public void scoreShow(){
        if(students.isEmpty())
            System.out.println(classNum+" has no grades yet");
        else
            System.out.println(classNum+" "+averageScore);
    }
    @Override
    public boolean equals(Object obj) {
        Class c = (Class) obj;
        return this.classNum.equals(c.classNum);
    }
}
class Student {
    private String name;
    private int stuID;
    private ArrayList<Double> totalScores = new ArrayList<>();
    public Student(String name, int stuID) {
        this.name = name;
        this.stuID = stuID;
    }
    public ArrayList<Double> getTotalScores() {
        return totalScores;
    }
    public int getStuID() {
        return stuID;
    }
    public void addTotalScore(double score){
        totalScores.add(score);
    }
    public int getAverageScore() {
        double score = 0.0;
        for(int i = 0; i < totalScores.size(); i++)
            score += totalScores.get(i);
        if(totalScores.size() == 0)
            return 0;
        else
            return (int)(score / totalScores.size());
    }

    public void scoreShow(){
        if(totalScores.isEmpty())
            System.out.println(stuID+" "+name+" did not take any exams");
        else
            System.out.println(stuID+" "+name+" "+getAverageScore());
    }
    @Override
    public boolean equals(Object obj) {
        Student s = (Student)obj;
        if(this.stuID == s.stuID)
            return true;
        else
            return false;
    }
}

class Course {
    private String course;
    private String property;
    private String form;
    private ArrayList<Integer> finalScores = new ArrayList<>();
    private ArrayList<Integer> usualScores = new ArrayList<>();
    private ArrayList<Double> totalScores = new ArrayList<>();

    public Course(String course, String property, String form) {
        this.course = course;
        this.form = form;
        this.property = property;
    }

    public String getCourse() {
        return course;
    }

    public String getForm() {
        return form;
    }
    public void addFinalScore(int score){
        finalScores.add(score);
    }
    public void addUsualScore(int score){
        usualScores.add(score);
    }
    public void addTotalScore(double score){
        totalScores.add(score);
    }
    public int getAverageFinal(){
        double score = 0.0;
        for(int i = 0; i < finalScores.size(); i++)
            score += finalScores.get(i);
        return (int)(score / finalScores.size());
    }
    public int getAverageUsual(){
        double score = 0.0;
        for(int i = 0; i < usualScores.size(); i++)
            score += usualScores.get(i);
        return (int)(score / usualScores.size());
    }
    public int getAverageTotal(){
        double score = 0.0;
        for(int i = 0; i < totalScores.size(); i++)
            score += totalScores.get(i);
        return (int)(score / totalScores.size());
    }
    public void scoreShow(){
        if(totalScores.isEmpty())
            System.out.println(course+" has no grades yet");
        else{
            if(form.equals("考试"))
                System.out.println(course+" "+getAverageUsual()+" "+getAverageFinal()+" "+getAverageTotal());
            else
                System.out.println(course+" "+getAverageFinal()+" "+getAverageTotal());
        }
    }
    @Override
    public boolean equals(Object obj) {
        Course c = (Course) obj;
        return this.course.equals(c.course);
    }
}

abstract class Score {
    protected int finalScore = 0;
    protected int usualScore = 0;
    public Score() {
    }
    public Score(int finalCourse) {
            this.finalScore = finalCourse;
    }
    public Score(int finalCourse, int usualCourse) {
            this.finalScore = finalCourse;
            this.usualScore = usualCourse;
    }
    public abstract double getTotalScore();
}


class ExamScore extends Score{
    public ExamScore(int finalCourse, int usualCourse) {
        super(finalCourse, usualCourse);
    }
    @Override
    public double getTotalScore(){
        return finalScore * 0.7 + usualScore * 0.3;
    }
}

class ResearchSourse extends Score{
    public ResearchSourse(int finalCourse){
        super(finalCourse);
    }
    @Override
    public double getTotalScore(){
        return finalScore;
    }
}

 

 类图

 设计分析

吃了上一次的菜单用数值储存数据的亏,这次成绩统计我用ArrayList储存数据,因为题目中要求最后输出结果时需要对学生,课程,班级按一定顺序排序,我只需要自定义sort排序方式就可以很轻松的完成,而查找也只是重写equals方法就可以实现,在考虑如何将学生,班级及课程的分数分开计算时,可以在每个对象中加入一个List来储存每个对象的分数,且在最后计算平均成绩时只需要遍历一次就可以完成平均分的计算。为了方便对数据进行操作且符合单一职责原则,用GradeData类来对所有数据进行操作,而避免了其他类之间产生关联。还有一点,这次作业对代码长度有限制,差不多四五百行就会超限,因此我写了很多方法来代替主方法中的代码,大量if-else判断放在方法中判断也减少了不少的代码量。

课程成绩统计程序-2

源代码

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Collections;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        GradeData gradeData = new GradeData();
        ArrayList<SelectedCourse> selectedCourses= new ArrayList<>();
        Pattern pattern = Pattern.compile("[0-9]*");
        String[] command = in.nextLine().split(" ");
        while (!command[0].equals("end") && !pattern.matcher(command[0]).matches()){
            if((command.length == 3) && command[0].length() <= 10){
                if((command[1].equals("必修")||command[1].equals("选修")||command[1].equals("实验"))&&(command[2].equals("考试")||command[2].equals("考察")||command[2].equals("实验"))){
                    if(!gradeData.getCourse().contains(new Course(command[0],"","")))
                        if(!gradeData.addCourse(command[0],command[1],command[2]))
                            System.out.println(command[0]+" : course type & access mode mismatch");
                }
                else
                    System.out.println("wrong format");
            }
            else
                System.out.println("wrong format");
            command = in.nextLine().split(" ");
        }
        while (!command[0].equals("end")){
            if(command.length >= 4) {
                SelectedCourse record = new SelectedCourse(command);
                if (record.judge()) {
                    if (!selectedCourses.contains(record)) {
                        int judge = gradeData.addCourseScore(command);
                        if (judge == -1)
                            System.out.println(command[2] + " does not exist");
                        else if (judge == -2)
                            System.out.println(command[0] + " " + command[1] + " : access mode mismatch");
                        else if(judge == -3){
                            command = in.nextLine().split(" ");
                            continue;
                        }
                        else if (judge == 0)
                            selectedCourses.add(record);
                        gradeData.addStudent(command,judge);
                        gradeData.addClass(command[0]);
                    }
                }
                else
                    System.out.println("wrong format");
            }
            else
                System.out.println("wrong format");
            command = in.nextLine().split(" ");
        }
        gradeData.studentSort();
        gradeData.courseSort();
        gradeData.classSort();
        gradeData.scorePrint();
    }
}
class GradeData {
    private ArrayList<Course> courses = new ArrayList<>();
    private ArrayList<Student> students = new ArrayList<>();
    private ArrayList<Class> classes = new ArrayList<>();
    private Score score = new ExamScore(0,0);

    public GradeData() {
    }
    public ArrayList<Course> getCourse() {
        return courses;
    }
    //添加课程信息
    public boolean addCourse(String course, String property, String form){
        if(course.length() > 10){
            System.out.println("wrong format");
            return true;
        }
        if(property.equals("必修") && !form.equals("考试"))
            return false;
        if(property.equals("选修") && !form.equals("考察"))
            return false;
        if(property.equals("实验") && !form.equals("实验"))
            return false;
        if(findCourse(course) >= 0)
            return true;
        if(findCourse(course) == -1)
            this.courses.add(new Course(course, property, form));
        return true;
    }
    public int addCourseScore(String[] command){
        String course = command[2];
        int labNum = Integer.parseInt(command[3]);
        int fScore = 0;
        int uScore = 0;
        int index = findCourse(course);
        if(index == -1){
            return -1;
        }
        Course replace = courses.get(index);
        if(command.length == 4 && replace.getForm().equals("考察")){
            fScore = Integer.parseInt(command[3]);
            score = new ResearchScore(fScore);
            replace.addFinalScore(fScore);
        }
        else if(command.length == 5 && replace.getForm().equals("考试")) {
            uScore = Integer.parseInt(command[3]);
            fScore = Integer.parseInt(command[4]);
            score = new ExamScore(fScore,uScore);
            replace.addFinalScore(fScore);
            replace.addUsualScore(uScore);
        }
        else if(replace.getForm().equals("实验")){
            if(labNum >=4 && labNum <= 9){
                if(labNum + 4 == command.length)
                    score = new LabScore(command);
                else
                    return -2;
            }
            else {
                System.out.println("wrong format");
                return -3;
            }
        }
        else{
            return -2;
        }
        replace.addTotalScore(score.getTotalScore());
        courses.set(index, replace);
        return 0;
    }
    public int findCourse(String course){
        Course judge = new Course(course,"","");
        return courses.indexOf(judge);
    }
    public void addStudent(String[] command,int judge){
        int stuID = Integer.parseInt(command[0]);
        String name = command[1];
        String course = command[2];
        int index = findStudent(stuID);
        if(index == -1)
            this.students.add(new Student(name, stuID));
        if(courses.contains(new Course(course,"",""))) {
            String form = courses.get(findCourse(course)).getForm();
            if(judge == 0) {
                if (form.equals("考试"))
                    score = new ExamScore(Integer.parseInt(command[4]), Integer.parseInt(command[3]));
                else if(form.equals("考察"))
                    score = new ResearchScore(Integer.parseInt(command[3]));
                else if(form.equals("实验"))
                    score = new LabScore(command);
                index = findStudent(stuID);
                Student replace = students.get(index);
                replace.addTotalScore(score.getTotalScore());
                students.set(index, replace);
            }
        }
    }
    public int findStudent(int stuID){
        Student judge = new Student("", stuID);
        return students.indexOf(judge);
    }
    public void addClass(String stuID){
        if(stuID.length() == 8 && findClass(stuID.substring(0,6)) == -1)
            classes.add(new Class(stuID.substring(0,6), -1));
        int index = findClass(stuID.substring(0,6));
        if(!students.get(findStudent(Integer.parseInt(stuID))).getTotalScores().isEmpty()){
            Class replace = classes.get(index);
            replace.addStudent(students.get(findStudent(Integer.parseInt(stuID))));
            classes.set(index, replace);
        }
    }
    public int findClass(String classNum){
        Class jugde = new Class(classNum, -1);
        return classes.indexOf(jugde);
    }
    public void courseSort(){
        Collections.sort(courses, new Comparator<Course>() {
            @Override
            public int compare(Course o1, Course o2) {
                Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
                Matcher m1 = p.matcher(o1.getCourse());
                Matcher m2 = p.matcher(o2.getCourse());
                if(m1.find()&&m2.find()){
                    if(o1.getCourse().compareTo(o2.getCourse()) > 0){
                        return 1;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) == 0){
                        return 0;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) < 0){
                        return -1;
                    }
                }
                else {
                    if(o1.getCourse().compareTo(o2.getCourse()) > 0){
                        return 1;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) == 0){
                        return 0;
                    }else if(o1.getCourse().compareTo(o2.getCourse()) < 0){
                        return -1;
                    }
                }
                return 0;
            }
        });
    }
    public void studentSort(){
        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getStuID() > o2.getStuID()){
                    return 1;
                }else if(o1.getStuID() == o2.getStuID()){
                    return 0;
                }else if(o1.getStuID() < o2.getStuID()){
                    return -1;
                }
                return 0;
            }
        });
    }
    public void classSort(){
        Collections.sort(classes, new Comparator<Class>() {
            @Override
            public int compare(Class o1, Class o2) {
                if(o1.getClassNum().compareTo(o2.getClassNum()) > 0){
                    return 1;
                }else if(o1.getClassNum().compareTo(o2.getClassNum()) == 0){
                    return 0;
                }else if(o1.getClassNum().compareTo(o2.getClassNum()) < 0){
                    return -1;
                }
                return 0;
            }
        });
    }
    public void scorePrint(){
        for (int i = 0; i < students.size(); i++)
            students.get(i).scoreShow();
        for (int i = 0; i < courses.size(); i++)
            courses.get(i).scoreShow();
        for (int i = 0; i < classes.size(); i++)
            classes.get(i).scoreShow();
    }
}
class SelectedCourse {
    public Course course;
    public Student student;
    public String[] command;
    public SelectedCourse(String[] command) {
        this.course = new Course(command[2],"","");
        this.student = new Student("",Integer.parseInt(command[0]));
        this.command = command;
    }
    public boolean judge(){
        Pattern pattern = Pattern.compile("0|[0-9]{1,2}|100");
        if(command[0].length() == 8 && command[1].length() <= 10){
            for(int i = 3; i < command.length; i++){
                if(!pattern.matcher(command[i]).matches())
                    return false;
            }
            return true;
        }
        else
            return false;

    }
    public boolean scorejudge(String[] command){
        Pattern pattern = Pattern.compile("0|[0-9]{1,2}|100");
        for(int i = 3; i < command.length; i++){
            if(pattern.matcher(command[i]).matches())
                return false;
        }
        return true;
    }
    public Course getCourse() {
        return course;
    }
    public Student getStudent() {
        return student;
    }
    @Override
    public boolean equals(Object obj) {
        SelectedCourse sc = (SelectedCourse) obj;
        if(this.course.getCourse().equals(sc.getCourse().getCourse())&&this.student.getStuID() == sc.getStudent().getStuID())
            return true;
        else
            return false;
    }
}
class Class {
    private String classNum;
    private int averageScore;
    private ArrayList<Student> students = new ArrayList<>();
    public Class(String classNum, int averageScore) {
        this.classNum = classNum;
        this.averageScore = averageScore;
    }
    public String getClassNum() {
        return classNum;
    }
    public void addStudent(Student student){
        students.add(student);
        double score = 0.0;
        for(int i = 0; i < students.size(); i++)
            score += students.get(i).getAverageScore();
        this.averageScore = (int)(score / students.size());
    }
    public int getAverageScore() {
        return averageScore;
    }
    public void scoreShow(){
        if(students.isEmpty())
            System.out.println(classNum+" has no grades yet");
        else
            System.out.println(classNum+" "+averageScore);
    }
    @Override
    public boolean equals(Object obj) {
        Class c = (Class) obj;
        return this.classNum.equals(c.classNum);
    }
}
class Student {
    private String name;
    private int stuID;
    private ArrayList<Integer> totalScores = new ArrayList<>();
    public Student(String name, int stuID) {
        this.name = name;
        this.stuID = stuID;
    }
    public ArrayList<Integer> getTotalScores() {
        return totalScores;
    }
    public int getStuID() {
        return stuID;
    }
    public void addTotalScore(int score){
        totalScores.add(score);
    }
    public int getAverageScore() {
        double score = 0.0;
        for(int i = 0; i < totalScores.size(); i++)
            score += totalScores.get(i);
        if(totalScores.size() == 0)
            return 0;
        else
            return (int)(score / totalScores.size());
    }

    public void scoreShow(){
        if(totalScores.isEmpty())
            System.out.println(stuID+" "+name+" did not take any exams");
        else
            System.out.println(stuID+" "+name+" "+getAverageScore());
    }
    @Override
    public boolean equals(Object obj) {
        Student s = (Student)obj;
        if(this.stuID == s.stuID)
            return true;
        else
            return false;
    }
}

class Course {
    private String course;
    private String property;
    private String form;
    private ArrayList<Integer> finalScores = new ArrayList<>();
    private ArrayList<Integer> usualScores = new ArrayList<>();
    private ArrayList<Integer> totalScores = new ArrayList<>();

    public Course(String course, String property, String form) {
        this.course = course;
        this.form = form;
        this.property = property;
    }

    public String getCourse() {
        return course;
    }

    public String getForm() {
        return form;
    }
    public void addFinalScore(int score){
        finalScores.add(score);
    }
    public void addUsualScore(int score){
        usualScores.add(score);
    }
    public void addTotalScore(int score){
        totalScores.add(score);
    }
    public int getAverageFinal(){
        double score = 0.0;
        for(int i = 0; i < finalScores.size(); i++)
            score += finalScores.get(i);
        return (int)(score / finalScores.size());
    }
    public int getAverageUsual(){
        double score = 0.0;
        for(int i = 0; i < usualScores.size(); i++)
            score += usualScores.get(i);
        return (int)(score / usualScores.size());
    }
    public int getAverageTotal(){
        double score = 0.0;
        for(int i = 0; i < totalScores.size(); i++)
            score += totalScores.get(i);
        return (int)(score / totalScores.size());
    }
    public void scoreShow(){
        if(totalScores.isEmpty())
            System.out.println(course+" has no grades yet");
        else{
            if(form.equals("考试"))
                System.out.println(course+" "+getAverageUsual()+" "+getAverageFinal()+" "+getAverageTotal());
            else if(form.equals("考察"))
                System.out.println(course+" "+getAverageFinal()+" "+getAverageTotal());
            else if(form.equals("实验"))
                System.out.println(course+" "+getAverageTotal());
        }
    }
    @Override
    public boolean equals(Object obj) {
        Course c = (Course) obj;
        return this.course.equals(c.course);
    }
}

abstract class Score {
    protected int finalScore = 0;
    protected int usualScore = 0;
    protected ArrayList<Integer> labScores = new ArrayList<>();
    public Score() {
    }
    public Score(int finalCourse) {
        this.finalScore = finalCourse;
    }
    public Score(int finalCourse, int usualCourse) {
        this.finalScore = finalCourse;
        this.usualScore = usualCourse;
    }
    public abstract int getTotalScore();
}


class ExamScore extends Score{
    public ExamScore(int finalCourse, int usualCourse) {
        super(finalCourse, usualCourse);
    }
    @Override
    public int getTotalScore(){
        return (int)(finalScore * 0.7 + usualScore * 0.3);
    }
}

class ResearchScore extends Score{
    public ResearchScore(int finalCourse){
        super(finalCourse);
    }
    @Override
    public int getTotalScore(){
        return finalScore;
    }
}
class LabScore extends Score{
    public LabScore(String[] labscore) {
        for(int i = 4; i < labscore.length; i++)
            super.labScores.add(Integer.parseInt(labscore[i]));
    }
    @Override
    public int getTotalScore(){
        double totalScore = 0.0;
        for(int score: labScores)
            totalScore += score;
        return (int)totalScore / labScores.size();
    }
}

 

类图

 

设计分析

这次成绩统计迭代加入了实验课分数的统计,因此我新加了一个LabGrade类代表实验课分数,实验课的多项成绩用ArrayList储存,方便遍历计算最终成绩。其他结构与上一次基本相似,因为上次设计感觉还算不错,因此这一次并没有花很多时间就完成了,而且这次作业中我将很多异常判断放到方法中判断,从而减少很多在主方法中的if-else语句,尽可能的保证功能完全的同时减少代码量。

 

课程成绩统计程序-3

 源代码

 

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        GradeData gradeData = new GradeData();
        ArrayList<SelectedCourse> selectedCourses= new ArrayList<>();
        Pattern pattern = Pattern.compile("[0-9]*");
        String[] command = in.nextLine().split(" ");
        while (!command[0].equals("end") && !pattern.matcher(command[0]).matches()){
            if(command[0].length() <= 10){
                if((command[1].equals("必修")||command[1].equals("选修")||command[1].equals("实验"))&&(command[2].equals("考试")||command[2].equals("考察")||command[2].equals("实验"))){
                    if(command[2].equals("实验")&&command.length < 5){
                        System.out.println("wrong format");
                    }
                    else{
                        if(!gradeData.getCourse().contains(new Course(command[0],"","")))
                            if(!gradeData.addCourse(command))
                                System.out.println(command[0]+" : course type & access mode mismatch");
                    }

                }
                else
                    System.out.println("wrong format");
            }
            else
                System.out.println("wrong format");
            command = in.nextLine().split(" ");
        }
        while (!command[0].equals("end")){
            if(command.length >= 4) {
                SelectedCourse record = new SelectedCourse(command);
                if (record.judge()) {
                    if (!selectedCourses.contains(record)) {
                        int judge = gradeData.addCourseScore(command);
                        if (judge == -1)
                            System.out.println(command[2] + " does not exist");
                        else if (judge == -2)
                            System.out.println(command[0] + " " + command[1] + " : access mode mismatch");
                        else if(judge == -3){
                            command = in.nextLine().split(" ");
                            continue;
                        }
                        else if (judge == 0)
                            selectedCourses.add(record);
                        gradeData.addStudent(command,judge);
                        gradeData.addClass(command[0]);
                    }
                }
                else
                    System.out.println("wrong format");
            }
            else
                System.out.println("wrong format");
            command = in.nextLine().split(" ");
        }
        gradeData.studentSort();
        gradeData.courseSort();
        gradeData.classSort();
        gradeData.scorePrint();
    }
}
class GradeData {
    private ArrayList<Course> courses = new ArrayList<>();
    private ArrayList<Student> students = new ArrayList<>();
    private ArrayList<Class> classes = new ArrayList<>();
    private Score score;

    public GradeData() {
    }
    public ArrayList<Course> getCourse() {
        return courses;
    }
    //添加课程信息
    public boolean addCourse(String[] command){
        String course = command[0];
        String property = command[1];
        String form = command[2];
        if(course.length() > 10){
            System.out.println("wrong format");
            return true;
        }
        if(property.equals("必修") && !form.equals("考试"))
            return false;
        if(property.equals("选修") && !form.equals("考察"))
            return false;
        if(property.equals("实验") && !form.equals("实验"))
            return false;
        if(findCourse(course) >= 0)
            return true;
        if(findCourse(course) == -1){
            if(form.equals("实验")){
                int labnum = Integer.parseInt(command[3]);
                double weights = 0.0;
                Float[] weight = new Float[command.length - 4];
                if(labnum >= 4 && labnum <= 9){
                    for(int i = 4; i < command.length; i++){
                        weight[i-4] = Float.parseFloat(command[i]);
                        weights += Float.parseFloat(command[i]);
                    }
                    if(weight.length != labnum){
                        System.out.println(course+" : number of scores does not match");
                        return true;
                    }
                    else if(Math.abs(weights - 1) > 0.00001){
                        System.out.println(course+" : weight value error");
                        return true;
                    }
                    else{
                        this.courses.add(new Course(course, property, form, labnum, weight));
                        return true;
                    }
                }
                else {
                    System.out.println("wrong format");
                    return true;
                }
            }
        }
        this.courses.add(new Course(course, property, form));
        return true;
    }
    public int addCourseScore(String[] command){
        String course = command[2];
        int fScore = 0;
        int uScore = 0;
        int index = findCourse(course);
        if(index == -1){
            return -1;
        }
        Course replace = courses.get(index);
        int totalScore = 0;
        if(command.length == 4 && replace.form.equals("考察")){
            fScore = Integer.parseInt(command[3]);
            ResearchScore score = new ResearchScore(fScore);
            totalScore = score.getTotalScore();
            replace.addFinalScore(fScore);
        }
        else if(command.length == 5 && replace.form.equals("考试")) {
            uScore = Integer.parseInt(command[3]);
            fScore = Integer.parseInt(command[4]);
            ExamScore score = new ExamScore(fScore,uScore);
            totalScore = score.getTotalScore();
            replace.addFinalScore(fScore);
            replace.addUsualScore(uScore);
        }
        else if(replace.form.equals("实验")){
            int labNum = replace.labnum;
            if(labNum + 3 == command.length){
                LabScore score = new LabScore(command, replace.weight);
                totalScore = score.getTotalScore();
            }
            else
                return -2;
        }
        else{
            return -2;
        }
        replace.addTotalScore(totalScore);
        courses.set(index, replace);
        return 0;
    }
    public int findCourse(String course){
        Course judge = new Course(course,"","");
        return courses.indexOf(judge);
    }
    public void addStudent(String[] command,int judge){
        int stuID = Integer.parseInt(command[0]);
        String name = command[1];
        String course = command[2];
        int index = findStudent(stuID);
        if(index == -1)
            this.students.add(new Student(name, stuID));
        if(courses.contains(new Course(course,"",""))) {
            String form = courses.get(findCourse(course)).form;
            if(judge == 0) {
                index = findStudent(stuID);
                Student replace = students.get(index);
                int totalScore = 0;
                if (form.equals("考试")){
                    ExamScore score = new ExamScore(Integer.parseInt(command[4]), Integer.parseInt(command[3]));
                    totalScore = score.getTotalScore();
                }
                else if(form.equals("考察")){
                    ResearchScore score = new ResearchScore(Integer.parseInt(command[3]));
                    totalScore = score.getTotalScore();
                }
                else if(form.equals("实验")){
                    Float[] weight = courses.get(findCourse(course)).weight;
                    LabScore score = new LabScore(command,weight);
                    totalScore = score.getTotalScore();
                }
                replace.addTotalScore(totalScore);
                students.set(index, replace);
            }
        }
    }
    public int findStudent(int stuID){
        Student judge = new Student("", stuID);
        return students.indexOf(judge);
    }
    public void addClass(String stuID){
        if(stuID.length() == 8 && findClass(stuID.substring(0,6)) == -1)
            classes.add(new Class(stuID.substring(0,6), -1));
        int index = findClass(stuID.substring(0,6));
        if(!students.get(findStudent(Integer.parseInt(stuID))).getTotalScores().isEmpty()){
            Class replace = classes.get(index);
            replace.addStudent(students.get(findStudent(Integer.parseInt(stuID))));
            classes.set(index, replace);
        }
    }
    public int findClass(String classNum){
        Class jugde = new Class(classNum, -1);
        return classes.indexOf(jugde);
    }
    public void courseSort(){
        Collections.sort(courses, new Comparator<Course>() {
            @Override
            public int compare(Course o1, Course o2) {
                Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
                Matcher m1 = p.matcher(o1.course);
                Matcher m2 = p.matcher(o2.course);
                if(m1.find()&&m2.find()){
                    if(o1.course.compareTo(o2.course) > 0){
                        return 1;
                    }else if(o1.course.compareTo(o2.course) == 0){
                        return 0;
                    }else if(o1.course.compareTo(o2.course) < 0){
                        return -1;
                    }
                }
                else {
                    if(o1.course.compareTo(o2.course) > 0){
                        return 1;
                    }else if(o1.course.compareTo(o2.course) == 0){
                        return 0;
                    }else if(o1.course.compareTo(o2.course) < 0){
                        return -1;
                    }
                }
                return 0;
            }
        });
    }
    public void studentSort(){
        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getStuID() > o2.getStuID()){
                    return 1;
                }else if(o1.getStuID() == o2.getStuID()){
                    return 0;
                }else if(o1.getStuID() < o2.getStuID()){
                    return -1;
                }
                return 0;
            }
        });
    }
    public void classSort(){
        Collections.sort(classes, new Comparator<Class>() {
            @Override
            public int compare(Class o1, Class o2) {
                if(o1.getClassNum().compareTo(o2.getClassNum()) > 0){
                    return 1;
                }else if(o1.getClassNum().compareTo(o2.getClassNum()) == 0){
                    return 0;
                }else if(o1.getClassNum().compareTo(o2.getClassNum()) < 0){
                    return -1;
                }
                return 0;
            }
        });
    }
    public void scorePrint(){
        for (int i = 0; i < students.size(); i++)
            students.get(i).scoreShow();
        for (int i = 0; i < courses.size(); i++)
            courses.get(i).scoreShow();
        for (int i = 0; i < classes.size(); i++)
            classes.get(i).scoreShow();
    }
}
class SelectedCourse {
    public Course course;
    public Student student;
    public String[] command;
    public SelectedCourse(String[] command) {
        this.course = new Course(command[2],"","");
        this.student = new Student("",Integer.parseInt(command[0]));
        this.command = command;
    }
    public boolean judge(){
        Pattern pattern = Pattern.compile("0|[0-9]{1,2}|100");
        if(command[0].length() == 8 && command[1].length() <= 10){
            for(int i = 3; i < command.length; i++){
                if(!pattern.matcher(command[i]).matches())
                    return false;
            }
            return true;
        }
        else
            return false;

    }
    public boolean scorejudge(String[] command){
        Pattern pattern = Pattern.compile("0|[0-9]{1,2}|100");
        for(int i = 3; i < command.length; i++){
            if(pattern.matcher(command[i]).matches())
                return false;
        }
        return true;
    }
    public Course getCourse() {
        return course;
    }
    public Student getStudent() {
        return student;
    }
    @Override
    public boolean equals(Object obj) {
        SelectedCourse sc = (SelectedCourse) obj;
        if(this.course.course.equals(sc.getCourse().course)&&this.student.getStuID() == sc.getStudent().getStuID())
            return true;
        else
            return false;
    }
}
class Class {
    private String classNum;
    private int averageScore;
    private ArrayList<Student> students = new ArrayList<>();
    public Class(String classNum, int averageScore) {
        this.classNum = classNum;
        this.averageScore = averageScore;
    }
    public String getClassNum() {
        return classNum;
    }
    public void addStudent(Student student){
        students.add(student);
        double score = 0.0;
        for(int i = 0; i < students.size(); i++)
            score += students.get(i).getAverageScore();
        this.averageScore = (int)(score / students.size());
    }
    public int getAverageScore() {
        return averageScore;
    }
    public void scoreShow(){
        if(students.isEmpty())
            System.out.println(classNum+" has no grades yet");
        else
            System.out.println(classNum+" "+averageScore);
    }
    @Override
    public boolean equals(Object obj) {
        Class c = (Class) obj;
        return this.classNum.equals(c.classNum);
    }
}
class Student {
    private String name;
    private int stuID;
    private ArrayList<Integer> totalScores = new ArrayList<>();
    public Student(String name, int stuID) {
        this.name = name;
        this.stuID = stuID;
    }
    public ArrayList<Integer> getTotalScores() {
        return totalScores;
    }
    public int getStuID() {
        return stuID;
    }
    public void addTotalScore(int score){
        totalScores.add(score);
    }
    public int getAverageScore() {
        double score = 0.0;
        for(int i = 0; i < totalScores.size(); i++)
            score += totalScores.get(i);
        if(totalScores.size() == 0)
            return 0;
        else
            return (int)(score / totalScores.size());
    }

    public void scoreShow(){
        if(totalScores.isEmpty())
            System.out.println(stuID+" "+name+" did not take any exams");
        else
            System.out.println(stuID+" "+name+" "+getAverageScore());
    }
    @Override
    public boolean equals(Object obj) {
        Student s = (Student)obj;
        if(this.stuID == s.stuID)
            return true;
        else
            return false;
    }
}

class Course {
    String course;
    String property;
    String form;
    int labnum;
    Float[] weight;
    ArrayList<Integer> finalScores = new ArrayList<>();
    ArrayList<Integer> usualScores = new ArrayList<>();
    ArrayList<Integer> totalScores = new ArrayList<>();

    public Course(String course, String property, String form) {
        this.course = course;
        this.form = form;
        this.property = property;
    }
    public Course(String course, String property, String form, int num, Float[] weight){
        this.course = course;
        this.form = form;
        this.property = property;
        this.labnum = num;
        this.weight = weight;
    }
    public void addFinalScore(int score){
        finalScores.add(score);
    }
    public void addUsualScore(int score){
        usualScores.add(score);
    }
    public void addTotalScore(int score){
        totalScores.add(score);
    }
    public int getAverageFinal(){
        double score = 0.0;
        for(int i = 0; i < finalScores.size(); i++)
            score += finalScores.get(i);
        return (int)(score / finalScores.size());
    }
    public int getAverageUsual(){
        double score = 0.0;
        for(int i = 0; i < usualScores.size(); i++)
            score += usualScores.get(i);
        return (int)(score / usualScores.size());
    }
    public int getAverageTotal(){
        double score = 0.0;
        for(int i = 0; i < totalScores.size(); i++)
            score += totalScores.get(i);
        return (int)(score / totalScores.size());
    }
    public void scoreShow(){
        if(totalScores.isEmpty())
            System.out.println(course+" has no grades yet");
        else{
            if(form.equals("考试"))
                System.out.println(course+" "+getAverageUsual()+" "+getAverageFinal()+" "+getAverageTotal());
            else if(form.equals("考察"))
                System.out.println(course+" "+getAverageFinal()+" "+getAverageTotal());
            else if(form.equals("实验"))
                System.out.println(course+" "+getAverageTotal());
        }
    }
    @Override
    public boolean equals(Object obj) {
        Course c = (Course) obj;
        return this.course.equals(c.course);
    }
}
class Score {
    int finalScore = 0;
    int usualScore = 0;
    ArrayList<Labgrade> labScores = new ArrayList<>();
    public Score() {
    }
    public Score(int finalCourse) {
        this.finalScore = finalCourse;
    }
    public Score(int finalCourse, int usualCourse) {
        this.finalScore = finalCourse;
        this.usualScore = usualCourse;
    }
}
class ExamScore{
    Score score;
    public ExamScore(int finalCourse, int usualCourse) {
        score = new Score(finalCourse ,usualCourse);
    }
    public int getTotalScore(){
        return (int)(score.finalScore * 0.7 + score.usualScore * 0.3);
    }
}

class ResearchScore{
    Score score;
    public ResearchScore(int finalCourse){
        score = new Score(finalCourse);
    }
    public int getTotalScore(){
        return score.finalScore;
    }
}
class LabScore{
    Score score = new Score();
    public LabScore(String[] labscore,Float[] weight) {
        for(int i = 3; i < labscore.length; i++)
            score.labScores.add(new Labgrade(Integer.parseInt(labscore[i]), weight[i-3]));
    }
    public int getTotalScore(){
        double totalScore = 0.0;
        for(Labgrade labgrade: score.labScores){
            totalScore += labgrade.score *labgrade.weight;
        }
        return (int)totalScore;
    }
}
class Labgrade{
    int score;
    double weight;
    public Labgrade(int score, double weight) {
        this.score = score;
        this.weight = weight;
    }
}

 

 

 

类图

 

 

 

设计分析

这是这个系列的最后一次迭代,为了体现继承与组合的区别,代码中所有的继承关系都需要改成组合,在我看来就是将原本的抽象父类变为原来子类的属性(可以从类图中看出原本继承的地方改为了组合),因为继承改为组合,原本多态就无法实现,因此需要对整体构建对象的代码部分进行修改,还有成绩统计中修改了计算成绩方式,原本的必修课和实验课每项成绩需要输入权重,这些在输入课程信息时先判断类型,后面直接利用for循环对输入语句拆分依次输入每项成绩权重,而其他计算方式与前面迭代版本无多大差别。

三、踩坑心得

 这几次训练集中踩坑的地方主要还是在课程成绩统计程序,还有统计Java关键词数量上,尤其时Java关键词上面因为统计关键词老说缺胳膊少腿,花费不少时间去找问题,试过很多方法,最后用一种比较另辟蹊径的方法解决。

课程成绩统计程序

 实现这个要求时其实还是遇到了一点困难,因为我的每一条信息用完一条就没用,在实现查重的方面,还是有点麻烦,为了解决查重问题,我用SelectedCourse类来创建对象来存储每一条输入的成绩信息。

 

每一次录入信息时对所有已输入的信息进行查询是否存在,如果存在则忽略此信息。

 

 还有其实是我没有看清题目的要求,把排序的顺序搞错了,我以为学生排序是按照成绩大小进行排序,后面才通过一次次测试才发现了这个错误,修改过后测试点就全过了

 

 统计Java关键词出现次数

刚开始统计关键词时,最先想到的就是有正则表达式对语句中的关键词进行一一匹配,理想很丰满,不出意外的是题目中出现的各种特殊情况基本无法通过,后面想到将语句中所有特殊字符替换成空格的方法,可以给每个词都拆分出来。

 这样确实大大减少了字符匹配的难度,但是其实我的字符匹配方式仍然有问题也就是关键词统计有问题,从而导致最后有个测试点无法通过。

 因为这个测试点没通过,我尝试了很多种方法,最后另辟蹊径利用set中的查询方法匹配关键词,对原本已经替换后的语句拆分成数组,之后一一查询,虽然麻烦一点,但是确实是解决问题的无奈之举

 

 

四、改进建议

1.代码设计时要更加符合面向对象原则,这样才能事半功倍。

2.系统学习Java,虽然现在是最后一次作业,但不代表Java的学习到达终点,需要往更高阶的学习

3.写代码的同时注意写注释,回头复习时避免看不懂自己写的代码

五、总结

 后面有几次训练集中老师都有意的限制我们的代码量,来让我们的代码变得更加精简更有效率,其实我更加能体会到模块化在编程中的重要性,减少代码的复用性很有必要,同时也强调了设计的重要性。OOP面向对象编程中需要遵守的几大原则也非常有用,多次迭代中确实能看得出来,可拓展性的实现可以给我们迭代更新时省时省力。

六、对本门课程进行客观性评价

教学理念(OBE)

虽然老师喜欢用压力来推动学生学习,带来高强度压力的同时让我头发掉了不少,也确实激发了学习热情,却容易形成一些极端现象,好的人会更好,摆烂的人最后也会更摆烂。

教学方法(边讲边练)

我觉得这种方法是非常有必要的,光听PPT讲的话很难将知识装入脑袋里,缺乏练习只会让知识更快的遗忘丢失,且难以理解。

教学组织(线上线下混合式教学)

线上线下教学确实缩短了在课堂上的时间,因为不需要讲基本的语法,讲语法是枯燥且乏味的,空出的时间可以帮助我们更加了解Java及面向对象编程的独特性,但是也有缺点,就是如果没有提前在线上预习的话,线下课缺少基础知识的情况很难听懂

教学过程(PTA题目集驱动)

很有必要,只有通过一些练习实战才能真正的掌握这门课程的知识,但还是有些不足,题量其实还行,但是时间太短,留给我们找到错误的时间太短,且测试点也很少,每次出现错误时没有测试点提醒很容易陷入到无头苍蝇的状态,浪费很多时间却毫无进展

教学模式(BOPPPS)

我们可以在整个过程中了解学习成果,自己及时做出调整。同时,尽量避免课堂组织流于表面形式, 老师发挥主导作用,更好地激发学生融入课堂教学的热情,激发我们自主学习的内在动机,激发课堂活力,以提高课堂效果。
posted @ 2023-06-27 23:25  qtiuan  阅读(10)  评论(0编辑  收藏  举报