第三次Blog作业

经过几个月的学习,面对对象课程的学习已经进入尾声,本次Blog将对题目集7-11的部分题目进行分析,还有简单的评价一下这门课程。

一、题目集部分分析

1、前言

在这一阶段由于知识基本已经学完,且部分题目与之前的比较相似,所以涉及到的知识点,包括有字符串的处理、正则表达式的使用、继承多态组合等类间关系、比较器和比较接口的使用,中间课程处理的几个题目涉及到了中文字符排序(这个可是重点,从未遇到过),到后面几次题目集之后就加了课外知识(map,set),集合框架有十分多的用处,个人感觉这个题目集是出得比较好的。

再就是题目集的数量,这一阶段相比较于上一阶段,题目集数量提升了比较多,包含有题目集pta7-pta11,还有随堂测试部分。题目大概有三个部分,其一为一如既往的菜单与衍生的课程统计类的题目,其二为map,set等等集合框架部分内容的学习与使用,其三为基本类间关系的使用。在这些题目集里面,花在第一部分的时间是最多的,由于题目的处理过程比较繁琐,几百上千行代码,测试点较多,比较考验思维能力和逻辑能力。而第二部分的map,set使用的题目集有些题目挺奇怪的,有些测试点是十分难以想到的,但相应的收获也比较多,在某一方面来说这样也算是成长了。第三部分比较基本,题目都是基础题目(可能是我太菜了),这三部分的题目都不算太多。

2、设计分析

这部分主要分析一些题目集里面的题目

(1)题目集7(7-1 菜单计价程序-5

这个题目大概就是在第一次菜单计价的基础上加了一部分的菜的属性和错误记录的判断,以及加上客户名字和号码在最后输出总价,将菜分为川菜,晋菜,浙菜,然后每种菜都有一个口味,需要在最后对口味值进行统计,这联系到实际的话就是店家统计客户在哪个口味值的比较多,帮助他进行菜品布局和原材料采购,还是比较有实际意义的。看题目所给的口味值范围:

川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;

晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;

浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;    

我比较好奇的是为什么浙菜没有很甜,是怕客户出现健康问题吗,回到题目,从这个菜所拥有的属性来讲,极其符合我们所学的知识——继承多态,口味值,价格,份额等等都是共同具有的属性,所以对于菜品类采用继承与多态,而对于点菜记录的这个Record类来说,因为代点菜与本桌菜多了一个属性,那就是别桌的代号,这好像有点不太符合我们的继承与多态,但是在实际使用过程中综合代码长度以及可复用性,还是采用继承与多态好一点,但在点菜父类中需要注意的是加上一个桌号,代表当前这个菜上到哪一桌。同时我们也需要一个Customer类,代表光顾店里的顾客(可以给他开会员吧)。为了方便,我把店家工作时间整合到Worktime类里面,防止代码过于臃肿,尽管这样做代码依旧很长,但是对于思路梳理还是挺有好处的,在这我没有太注意单一职责原则,导致代码长度长,后续可以继续优化。对于类间结构关系已经书写完成,附上我的类图:

 在上面类图中,由于我是将WorkTime不当成可以实体化的类来使用的,所以就没有和其它的2类有联系。Agent就是处理相关输入信息的一个类。

接下就该看看SourceMonitor生成的代码分析图

 953行,可以看到最大复杂度是44,平均是2.22,最大函数嵌套深度是7,然后平均函数嵌套深度是1.92,有14个类,注释占了14%,由于代码没有书写好,圈复杂度过大了,总体来说这个代码的效果并不好,需要再进一步优化。

(2)题目集8(课程成绩统计程序-1

这个课程成绩统计程序和前面的菜单程序相似,将课程换成菜品,再将用户改成学生,再依据输入的字符串进行一些判断,筛选出正确的信息,相应的课有两个性质——必修,选修对应菜系,然后就是考核方式需要注意一下。对于这个题目,根据题目所给类图采取的是设计一个课程类(Course),再去实体化,一个抽象成绩类(AbstractScore),有考查成绩和考试成绩两部分继承它,在设计一个学生类,班级类组合学生,最后再由一个选课成绩类去组合学生类,课程类,成绩类。这种设计方式挺奇异的,虽然学生与成绩和课程之间的耦合关系并不高,但是为什么不把成绩作为学生的属性进行设计呢,这样也能够方便后续计算成绩。可能这个课程和成绩并不是属于学生的,不需要设计成学生的属性。
附上类图:

Agent一如既往是进行输入信息处理的,AllCourse则是课程菜单。再来看看SourceMonitor生成的代码分析图:

 可以看到Classes是10,代表有10个类,然后就是最大圈复杂度13,平均圈复杂度是1.73,最大函数嵌套深度是4,平均函数嵌套深度是1.45,有382行代码,注释占了9.9%,从这些数据来看的话效果还是比上一题好的,可能是代码数量较少吧,全圈复杂度降到了13,但依旧是很高,对于代码书写确实缺失一定的经验和总结,只能经过不断地训练慢慢进行降低。

(3)题目集9(统计Java程序中关键词的出现次数)

这个题目的关键是map和set的使用,53个关键字可以在网上百度,最开始做这个题目的时候是想要将关键字作为一个类的,但后面老师要求只要60行以内,所以就只能精简代码了。

说下我的做题逻辑,先将53个关键字存入一个set里面,再开一个map存储出现次数,在将所有的代码合成一段,再将其中的多行注释删掉,再分开,删掉单行注释,再统计更新关键字的数量。只有一个类,代码数量较少,可以看下SourceMonitor生成的代码分析图:

 代码53行,最大复杂度为1,最大函数嵌套深度为4,平均深度为1.34,注释占27%,从这些数据来看,将复杂度控制在1是非常不错的,尽管代码数量较少。

(4)题目集10(课程成绩统计程序-2)

这个题目集包含了课程成绩统计程序-2这个题目,是题目集8的课程成绩统计程序的扩展,主要是增加了一门实验课和相关错误筛查,需要注意的是题目说实验成绩是有次数限制的,最后取平均成绩。依旧采用之前的部分设计方式,做一些小改变。相应的课有三个性质——必修,选修,实验,然后就是考核方式需要注意一下。对于这个题目,根据题目所给类图采取的是设计一个课程类(Course),再去实体化,一个抽象成绩类(AbstractScore),有考查成绩和考试成绩、实验成绩继承它,在设计一个学生类,班级类组合学生,最后再由一个选课成绩类(SelsectCourse)去组合学生类,课程类,成绩类。总体构造相似,就筛查错误这方面要花点心思。这里我将所有课程抽象成一个抽象父类(AbstractCourse),再衍生出三个子类(实验课,必修课,选修课),增加了代码长度,但是增加了可扩展性。看下类图:

 结构上还是比较清晰的,就是生成的类图之间的线条画的不太好。这是技术问题,莫得办法。再来看看SourceMonitor生成的代码分析图:

 可以看到行数是459行,有13个类,最大圈复杂度是17,平均圈复杂度是1.75,最大函数嵌套深度是4,平均圈复杂度是1.41,注释占了18.1%。从这些数据来看的话,与上一个成绩统计程序相比,圈复杂度增加的地方应该是错误的判断嵌套了挺多if,嵌套层数倒是没有改变,毕竟是代码迭代。

(5)题目集11( 课程成绩统计程序-3

这次题目集依旧是课程成绩统计程序的升级版,将实验课的次数改成了固定,无法改变,要求修改类之间关系:将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。我认为应该是将成绩的属性给揉和成一个分项成绩类,再让课程成绩组合它,大致上与上一次构造相差不大,看类图:

 将AbstractScore删掉了,也就不需要什么实验成绩,必修课程成绩,选修课程成绩。其它基本与上个题目相似。再来看看SourceMonitor生成的代码分析图:

 可以看到行数是523行,有10个类,最大圈复杂度是17,平均圈复杂度是1.72,最大函数嵌套深度是4,平均圈复杂度是1.31,注释占了16.6%。从这些数据来看的话,与上一个成绩统计程序相比,基本与课程成绩统计程序-2的数据类似,就是代码行数多了点,然后平均的复杂度,深度都有所下降,依旧是代码迭代。

3、采坑心得

在这部分,将对之前的题目涉及到的一些容易忽略的问题和容易错误的点,再加上我的代码。

(1)题目集7(7-1 菜单计价程序-5)

对于这一题,套路都是之前的菜单程序的,delete error要加上英文分号,但是他题目上并不是这样写的。题目提醒了在算口味值的时候需要将代点菜信息加入进去,这点比较诡异。按照常理来说不应该是被点的桌号承担这个口味评估,估计是为了降低题目难度吧。还有一个点比较容易忽略,就是看图:

 这个测试点当时卡了挺久,审题4遍后发现下面这个

 就是这个测试点卡了挺久,看不懂这个操作,比较奇怪,可能是为了用空格来说明那个口味值。最后再注意口味值的计算方法,

川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;

晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;

浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;    

都是0-几级,不是1开始的,这点需要注意,最后附上我的测试结果和代码:

代  码
点击展开
 import java.util.ArrayList;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.LocalTime;
public class Main {
    public  static void main(String []args){
        Agent agent = new Agent();
        agent.start();
    }
}

abstract class AbstractDish {
    private int unit_price;//单价
    private String dishName;//菜品名
    private String dishClass = " ";
    //构造和get set
    public AbstractDish() {
    }

    public AbstractDish( int unit_price, String dishName) {
        super();
        this.unit_price = unit_price;
        this.dishName = dishName;
    }

    public AbstractDish(int unit_price, String dishName, String dishClass) {
        this.unit_price = unit_price;
        this.dishName = dishName;
        this.dishClass = dishClass;
    }

    public String getDishClass() {
        return dishClass;
    }

    public void setDishClass(String dishClass) {
        this.dishClass = dishClass;
    }

    public int getUnit_price() {
        return unit_price;
    }

    public void setUnit_price(int unit_price) {
        this.unit_price = unit_price;
    }

    public String getDishName() {
        return dishName;
    }

    public void setDishName(String dishName) {
        this.dishName = dishName;
    }
    public abstract int getPrice(int portion,int num);

    public abstract boolean checkTaste(int taste);
    public void updateUnit_price(String s){     //更新菜价
        String rightPrice = "[0-9]{0,}";
        if(!s.matches(rightPrice)){
            System.out.println("wrong format");
            return;
        }
        else
            setUnit_price(Integer.parseInt(s));
    }
}

abstract class AbstractRecord {
    private int recordNum;//点菜序号
    private int num;    //份数
    private int portion;    //份额
    private int taste;  //口味
    private AbstractDish dish;  //菜品
    private int otherTableNum = -1;
    private boolean isBeOtherRecord = false;        //记录是否是被其它桌点的菜
    private boolean delete = false;     //该记录是否被删除

    public boolean isBeOtherRecord() {
        return isBeOtherRecord;
    }

    public void setBeOtherRecord(boolean beOtherRecord) {
        isBeOtherRecord = beOtherRecord;
    }

    public AbstractRecord(int recordNum, int num, int portion, AbstractDish dish) {      //本桌普通菜
        this.recordNum = recordNum;
        this.num = num;
        this.portion = portion;
        this.dish = dish;
    }

    public AbstractRecord(int recordNum, int num, int portion, int taste, AbstractDish dish) {       //本桌特色菜
        this.recordNum = recordNum;
        this.num = num;
        this.portion = portion;
        this.taste = taste;
        this.dish = dish;
    }

    public AbstractRecord(int recordNum, int num, int portion, int taste, AbstractDish dish, int otherTableNum) {   //代点特色菜
        this.recordNum = recordNum;
        this.num = num;             //份数
        this.portion = portion;
        this.otherTableNum = otherTableNum;
        this.taste = taste;
        this.dish = dish;
    }

    public AbstractRecord(int recordNum, int num, int portion ,AbstractDish dish, int otherTableNum) {      //代点普通菜
        this.recordNum = recordNum;
        this.num = num;
        this.portion = portion;
        this.dish = dish;
        this.otherTableNum = otherTableNum;
    }

    public boolean isDelete() {
        return delete;
    }

    public void setDelete(boolean delete) {
        this.delete = delete;
    }

    public AbstractRecord() {

    }

    public int getRecordNum() {
        return recordNum;
    }

    public void setRecordNum(int recordNum) {
        this.recordNum = recordNum;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public int getOtherTableNum() {
        return otherTableNum;
    }

    public AbstractDish getDish() {
        return dish;
    }

    public void setDish(Dish dish) {
        this.dish = dish;
    }

    public void setOtherTableNum(int otherTableNum) {
        this.otherTableNum = otherTableNum;
    }

    public int getPortion() {
        return portion;
    }

    public void setPortion(int portion) {
        this.portion = portion;
    }

    public int getTaste() {
        return taste;
    }

    public void setTaste(int taste) {
        this.taste = taste;
    }

    public int getTotalPrice() {
        return dish.getPrice(portion,num);
    }
    public abstract void pf();      //本桌
    public abstract void pf(int orderNum);//代点菜信息输出
}

class Agent {
    private ArrayList<Order> orderList = new ArrayList<>();
    public Agent() {
    }
    public void start(){
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        while(s.indexOf("table")==-1&&!s.equals("end")){        //读入菜品信息
            String str[] = s.split(" ");
            if(str.length!=2&&str.length!=4){
                System.out.println("wrong format");
                s = in.nextLine();
                continue;
            }
            if(!Menu.checkDishValid(s)) {
                System.out.println("wrong format");
                s = in.nextLine();
                continue;
            }
            Menu.addDish(s);
            s = in.nextLine();
        }
        while(s.indexOf("table")!=-1&&!s.equals("end")){        //读取桌号
            int count = 0;      //记录该订单是否正确
            String str[] = s.split(" ");
            if(str[3].length()>10){
                System.out.println("wrong format");
                s = in.nextLine();
                while (s.indexOf("table")==-1&&!s.equals("end"))        //当前桌信息作废
                    s = in.nextLine();
                continue;
            }
            if(str.length!=7||!checkTableNum(str[1])||!checkPhone(str[4])||
                    !WorkTime.checkOrderDate(str[5])||!WorkTime.checkOrderTime(str[6])){  //桌号格式检查
                System.out.println("wrong format");
                s = in.nextLine();
                while (s.indexOf("table")==-1&&!s.equals("end"))        //当前桌信息作废
                    s = in.nextLine();
                continue;
            }
            Order order = new Order();
            order.setOrder(s);

            if(order.checkIsWorkTime()) {       //检查是否在工作时间
                System.out.println("table " + order.getTableNum() + ": ");
                s = in.nextLine();
            }
            else{
                System.out.println("table "+order.getTableNum()+" out of opening hours");
                count = 1;
                s = in.nextLine();
                while (s.indexOf("table")==-1&&!s.equals("end"))        //当前桌信息作废
                    s = in.nextLine();
                continue;
            }

            while(s.indexOf("table")==-1&&!s.equals("end")){        //点菜信息处理
                String rightNumber = "[0-9]{0,}";
                int count1 = 0;     //查看点菜是否添加完成
                str= s.split(" ");
                if(Menu.searchDish(str[0])!=null) {       //更新单价
                    Menu.updateUnit_price(s);
                    s = in.nextLine();
                    continue;
                }
                if(str.length==2&&s.indexOf("delete")!=-1) {      //删除记录
                    if (!order.deleteRecord(s))
                        System.out.println("delete error;");
                    s = in.nextLine();
                    continue;
                }
//                if(!str[0].matches(rightNumber)){
//                    Menu.updateUnit_price(s);
//                }
                if(str.length==4) {     //本卓普通菜记录
                    count1 = order.addRecord(s);
                }

                if(str.length==5){      //本桌特色菜或者代点普通菜
                    String number = "[0-9]{0,}";
                    if(str[1].matches(number)){     //代点普通菜
                        count1 = order.addOtherRecord(s);
                    }
                    else{
                        count1 = order.addRecord(s);     //本桌特色菜
                    }
                }

                if(str.length==6){      //代点特色菜
                    for(int i = 0;i<orderList.size();i++){
                        if(orderList.get(i).getTableNum()==Integer.parseInt(str[0])){
                            orderList.get(i).addOtherRecord(s);
                            orderList.get(i).getRecordList().get(orderList.get(i).getRecordList().size()-1).setBeOtherRecord(true);
                            orderList.get(i).getRecordList().get(orderList.get(i).getRecordList().size()-1).setDelete(true);
                        }
                    }
                    count1 = order.addOtherRecord(s);
                }
                if(count1==0)
                    order.pf();     //输出当前点菜信息

                s = in.nextLine();
            }

            //处理当前桌完成
            orderList.add(order);
        }

        for(int i=0;i<orderList.size();i++){
//            System.out.println("table "+orderList.get(i).getTableNum()+": "+orderList.get(i).getEarlyAllPrice()+" "+orderList.get(i).getAllPrice()+"")
            orderList.get(i).printf();
        }

        ArrayList<Customer> customers = new ArrayList<>();          //顾客类
        for(int i = 0;i<orderList.size();i++){
            if(i==0){
                customers.add(new Customer(orderList.get(i).getCustomerName(),
                        orderList.get(i).getPhone(),orderList.get(i).getAllPrice()));
            }
            else{
                int count = 0;
                for(int j = 0;j<customers.size();j++){     //筛查相等名字
                    if(orderList.get(i).getCustomerName().equals(customers.get(j).getName())){
                        count = 1;
                        customers.get(j).setSumMoney(customers.get(j).getSumMoney()+orderList.get(i).getAllPrice());
                        break;
                    }
                }
                if(count == 1)
                    continue;
                for(int j=0;j<customers.size();j++){
                    if(orderList.get(i).getCustomerName().compareToIgnoreCase(customers.get(j).getName())<0){
                        count = 1;
                        customers.add(j,new Customer(orderList.get(i).getCustomerName(),
                                orderList.get(i).getPhone(),orderList.get(i).getAllPrice()));
                        break;
                    }
                }
                if(count == 0){
                    customers.add(new Customer(orderList.get(i).getCustomerName(),
                            orderList.get(i).getPhone(),orderList.get(i).getAllPrice()));
                }
            }
        }
        //输出顾客信息
        for(int i =0;i<customers.size();i++){
            System.out.println(customers.get(i).getName()+" "+customers.get(i).getPhone()+" "+customers.get(i).getSumMoney());
        }
    }

    public boolean checkTableNum(String s){
        String rightNum = "[0-9]{0,}";
        if(s.matches(rightNum))
            return true;
        return false;
    }

    public boolean checkPhone(String s){
        String rightPhone = "1(8(0|9|1)|3(3|5|6))[0-9]{8}";
        if(s.matches(rightPhone))
            return true;
        return false;
    }
}


class ChuanDish extends AbstractDish{
    public ChuanDish() {
    }

//    public ChuanDish(int unit_price, String dishName) {
//        super( unit_price, dishName);
//    }

    public ChuanDish(int unit_price, String dishName, String dishClass) {
        super(unit_price, dishName, dishClass);
    }

    @Override

    public int getPrice(int portion,int num){       //portion 是份额,num是份数
        int sum;        //总价
        if(portion==1)
            sum = getUnit_price() * num;
        else if(portion==2)
            sum = (int)(getUnit_price()* 1.5  + 0.5)* num ;
        else
            sum = getUnit_price() * num * 2;
        return sum;
    }

    @Override
    public boolean checkTaste(int taste) {
        if(taste<6&&taste>=0)
            return true;
        System.out.println("spicy num out of range :"+taste);
        return false;
    }
}

class Customer {
    private String name;
    private String phone;
    private int sumMoney;

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

    public Customer() {
    }

    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 getSumMoney() {
        return sumMoney;
    }

    public void setSumMoney(int sumMoney) {
        this.sumMoney = sumMoney;
    }
}

class Dish extends AbstractDish{
    //构造和get set
    public Dish() {
    }

    public Dish(int unit_price, String dishName) {
        super(unit_price,dishName);
    }

    @Override
    public int getPrice(int portion,int num){       //portion 是份额,num是份数
        int sum;        //总价
        if(portion==1)
            sum = getUnit_price() * num;
        else if(portion==2)
            sum = (int)(getUnit_price() * 1.5  + 0.5)* num;
        else
            sum = getUnit_price() * num * 2;
        return sum;
    }

    @Override
    public boolean checkTaste(int taste) {
        return false;
    }

}

class JinDish extends AbstractDish{
    public JinDish() {
    }

//    public JinDish(int unit_price, String dishName) {
//        super(unit_price, dishName);
//    }

    public JinDish(int unit_price, String dishName, String dishClass) {
        super(unit_price, dishName, dishClass);
    }

    @Override
    public int getPrice(int portion,int num){       //portion 是份额,num是份数
        int sum;        //总价
        if(portion==1)
            sum = getUnit_price() * num;
        else if(portion==2)
            sum = (int)(getUnit_price() * 1.5 + 0.5)* num ;
        else
            sum = getUnit_price() * num * 2;
        return sum;
    }

    @Override
    public boolean checkTaste(int taste) {
        if(taste<5&&taste>=0)
            return true;
        System.out.println("acidity num out of range :"+taste);
        return false;
    }
}

class Menu {
    public static ArrayList<AbstractDish> dishArrayList = new ArrayList<>();

    public static ArrayList<AbstractDish> getDishArrayList() {
        return dishArrayList;
    }

    public static void setDishArrayList(ArrayList<AbstractDish> dishArrayList) {
        Menu.dishArrayList = dishArrayList;
    }

    public Menu() {
    }
    public static void addDish(String s){
        String []str = s.split(" ");
        for(int i  =0;i<dishArrayList.size();i++){
            if(dishArrayList.get(i).getDishName().equals(str[0])){
                if(str.length==2)
                    dishArrayList.get(i).updateUnit_price(str[1]);
                else
                    dishArrayList.get(i).updateUnit_price(str[2]);
                return;
            }
        }
        if(str.length==2){
            dishArrayList.add(new Dish(Integer.parseInt(str[1]),str[0]));
        }
        else if(str[1].equals("川菜"))
            dishArrayList.add(new ChuanDish(Integer.parseInt(str[2]),str[0],"川菜"));
        else if(str[1].equals("晋菜"))
            dishArrayList.add(new JinDish(Integer.parseInt(str[2]),str[0],"晋菜"));
        else if(str[1].equals("浙菜"))
            dishArrayList.add(new ZheDish(Integer.parseInt(str[2]),str[0],"浙菜"));
    }
    public static boolean checkDishValid(String s){        //检查菜谱信息是否合法
        String price = "[0-9]{0,}";      //菜价格式
        String class1 = "川菜";       //菜品种类
        String class2 = "晋菜";
        String class3 = "浙菜";
        String [] str = s.split(" ");
        if(str.length==2){          //非特色菜
            if(!str[1].matches(price))
                return false;
            return true;
        }
        else if(str.length==4){     //特色菜
            if(!str[3].equals("T"))
                return false;
            if(!str[2].matches(price))
                return false;
            if(str[1].matches(class1)||str[1].matches(class2)||str[1].matches(class3))
                return true;
        }
            return false;
    }
    public static AbstractDish searchDish(String s){        //寻找菜品
        for(AbstractDish d:dishArrayList){
            if(d.getDishName().equals(s))
                return d;
        }
        return null;
    }
    public static void updateUnit_price(String s){      //更新菜单信息
        String str[] = s.split(" ");
        for(int i = 0;i<dishArrayList.size()-1;i++){
            if(dishArrayList.get(i).getDishName().equals(str[0])) {
                if(str.length==2)
                    dishArrayList.get(i).updateUnit_price(str[1]);
                else
                    dishArrayList.get(i).updateUnit_price(str[2]);
                return ;
            }
        }
        System.out.println("wrong format");
    }
}

class Order {
    private ArrayList<AbstractRecord> recordList = new ArrayList();
    private int tableNum;       //桌号
    private LocalDate tableDate;    //桌子日期
    private LocalTime tableTime;    //桌子时间
    private String customerName;    //用户名
    private String Phone;       //用户电话


    public Order( int tableNum, LocalDate tableDate, LocalTime tableTime, String customerName, String phone) {
        this.tableNum = tableNum;
        this.tableDate = tableDate;
        this.tableTime = tableTime;
        this.customerName = customerName;
        Phone = phone;
    }

    public Order() {

    }

    public ArrayList<AbstractRecord> getRecordList() {
        return recordList;
    }

    public void setRecordList(ArrayList recordList) {
        this.recordList = recordList;
    }

    public int getTableNum() {      //设置订单序号
        return tableNum;
    }

    public void setTableNum(int tableNum) {     //设置订单序号
        this.tableNum = tableNum;
    }

    public LocalDate getTableDate() {   //获得订单创建日期
        return tableDate;
    }

//    public void setTableDate(LocalDate tableDate) { //设置订单创建日期
//        this.tableDate = tableDate;
//    }

    public LocalTime getTableTime() {       //获得订单成立时间
        return tableTime;
    }

//    public void setTableTime(LocalTime tableTime) { //设置订单成立时间
//        this.tableTime = tableTime;
//    }

    public String getCustomerName() {       //获得顾客姓名
        return customerName;
    }

    public void setCustomerName(String customerName) {      //设置顾客姓名
        this.customerName = customerName;
    }

    public String getPhone() {  //获得电话
        return Phone;
    }

    public void setPhone(String phone) {        //设置电话号码
        Phone = phone;
    }
    public int addRecord(String s){
        String []str = s.split(" ");
        if(Menu.searchDish(str[1])==null) {         //菜品不存在
            System.out.println(str[1] + " does not exist");
            return 1;
        }
        if(str.length==5&&Menu.searchDish(str[1]).checkTaste(Integer.parseInt(str[2]))) {      //特色菜
            recordList.add(new Record(Integer.parseInt(str[0]), Integer.parseInt(str[4]),
                    Integer.parseInt(str[3]), Integer.parseInt(str[2]), Menu.searchDish(str[1])));
            return 0;
        }
        if(str.length==4) {     //普通菜
            recordList.add(new Record(Integer.parseInt(str[0]), Integer.parseInt(str[3]),
                    Integer.parseInt(str[2]), -1, Menu.searchDish(str[1])));
            return 0;
        }
        return 1;
    }

    public int addOtherRecord(String s){       //代点菜
        String []str = s.split(" ");
        if(Menu.searchDish(str[2])==null) {     //检查是否存在菜品
            System.out.println(str[1] + " does not exist");
            return 1;
        }
        if(str.length==6&&Menu.searchDish(str[2]).checkTaste(Integer.parseInt(str[3]))) {      //特色菜
            recordList.add(new OtherRecord(Integer.parseInt(str[1]), Integer.parseInt(str[5]),
                    Integer.parseInt(str[4]), Integer.parseInt(str[3]), Menu.searchDish(str[2]), Integer.parseInt(str[0])));
            return 0;
        }
        if(str.length==5)       //普通菜
        {
            recordList.add(new OtherRecord(Integer.parseInt(str[1]),Integer.parseInt(str[4]),
                    Integer.parseInt(str[3]),-1,Menu.searchDish(str[2]),Integer.parseInt(str[0])));
            return 0;
        }
        return 1;
    }
    public boolean deleteRecord(String s){      //删除该记录
        String []str = s.split(" ");
        for(AbstractRecord re : recordList){
            if(re.getRecordNum()==Integer.parseInt(str[0])){
                re.setDelete(true);
                return true;
            }
        }
        return false;
    }

    public void setTableTime(String s){     //设置订单创建时间
        String []str = s.split("/");
        int hours = Integer.parseInt(str[0]);
        int minutes = Integer.parseInt(str[1]);
        int seconds = Integer.parseInt(str[2]);
        this.tableTime = LocalTime.of(hours,minutes,seconds);
    }

//    public boolean isLeapYear(int year){        //判断是否是闰年
//        return (year%4==0&&year%100!=0)||year%400==0;
//    }
    public void setTableDate(String s){     //设置订单创建时间
        String []str = s.split("/");
        int year = Integer.parseInt(str[0]);
        int month = Integer.parseInt(str[1]);
        int day = Integer.parseInt(str[2]);
        this.tableDate = LocalDate.of(year,month,day);
    }
    public boolean checkIsWorkTime(){   //检查是否在工作时间
        return WorkTime.checkIsWorkTime(tableDate,tableTime);
    }
    public int getDiscount(){       //获得折扣
        return WorkTime.getDiscount(tableDate,tableTime);
    }
    public int getEarlyAllPrice(){      //获得未打折的总价
        int sum = 0;
        for(int i = 0;i<recordList.size();i++){
            if(!recordList.get(i).isDelete())
                sum +=recordList.get(i).getTotalPrice();
        }
        return sum;
    }
    public int getAllPrice(){       //获得打折后的总价
        // addPortion();
        int sum = 0;        //普通菜的总价
        int sum1 = 0;       //特色菜的总价
        int weekNum = tableDate.getDayOfWeek().getValue();
        if(weekNum<6)
            weekNum = 7;
        else
            weekNum = 10;
        for(int i = 0;i<recordList.size();i++){
            if(recordList.get(i).isDelete())        //判断是否被删
                continue;
            if(!(recordList.get(i).getTaste()==-1))
                sum1+=(int)(recordList.get(i).getTotalPrice()*(weekNum/10.0)+0.5);
            else
                sum+=(int)(recordList.get(i).getTotalPrice()*(getDiscount()/10.0)+0.5);
        }
        //return (int)(sum1*(weekNum/10.0)+sum*(getDiscount()/10.0)+0.5);
        return sum1+sum;
    }

    public void setOrder(String s){
        String str[] = s.split(" ");
        setTableNum(Integer.parseInt(str[1]));
        setCustomerName(str[3]);
        setPhone(str[4]);
        setTableDate(str[5]);
        setTableTime(str[6]);
    }
    public int getChuanAllTaste(){       //计算当前桌川菜的口味
        int num = 0;        //所有这种菜的口味
        for(int i= 0;i<recordList.size();i++){
            if(recordList.get(i).getDish().getDishClass().equals("川菜")&&(!recordList.get(i).isDelete()
                    &&recordList.get(i).getOtherTableNum()==-1||recordList.get(i).isBeOtherRecord())) {
                num += recordList.get(i).getTaste()*recordList.get(i).getNum();
            }
        }
        return num;
    }

    public int getChuanAllNum(){        //获得当前桌的川菜份数
        int sum = 0;        //总份数
        for(int i= 0;i<recordList.size();i++){
            if(recordList.get(i).getDish().getDishClass().equals("川菜")&&(!recordList.get(i).isDelete()
                    &&recordList.get(i).getOtherTableNum()==-1||recordList.get(i).isBeOtherRecord())) {
                sum += recordList.get(i).getNum();
            }
        }
        return sum;
    }

    public int getJinAllTaste(){       //计算当前桌晋菜的口味
        int num = 0;        //所有这种菜的口味
        for(int i= 0;i<recordList.size();i++){
            if(recordList.get(i).getDish().getDishClass().equals("晋菜")&&(!recordList.get(i).isDelete()
                    &&recordList.get(i).getOtherTableNum()==-1||recordList.get(i).isBeOtherRecord())) {
                num += recordList.get(i).getTaste()*recordList.get(i).getNum();
            }
        }
        return num;
    }

    public int getJinAllNum(){       //计算当前桌晋菜的口味
        int sum = 0;        //总份数
        for(int i= 0;i<recordList.size();i++){
            if(recordList.get(i).getDish().getDishClass().equals("晋菜")&&(!recordList.get(i).isDelete()
                    &&recordList.get(i).getOtherTableNum()==-1||recordList.get(i).isBeOtherRecord())){
                sum += recordList.get(i).getNum();
            }
        }
        return sum;
    }
    public int getZheAllTaste(){       //计算当前桌浙菜的口味
        int num = 0;        //所有这种菜的口味
        for(int i= 0;i<recordList.size();i++){
            if(recordList.get(i).getDish().getDishClass().equals("浙菜")&&(!recordList.get(i).isDelete()
                    &&recordList.get(i).getOtherTableNum()==-1||recordList.get(i).isBeOtherRecord())) {
                num += recordList.get(i).getTaste()*recordList.get(i).getNum();
            }
        }
        return num;
    }

    public int getZheAllNum(){       //计算当前桌浙菜的口味
        int sum = 0;        //总份数
        for(int i= 0;i<recordList.size();i++){
            if(recordList.get(i).getDish().getDishClass().equals("浙菜")&&(!recordList.get(i).isDelete()
                    &&recordList.get(i).getOtherTableNum()==-1||recordList.get(i).isBeOtherRecord())) {
                sum += recordList.get(i).getNum();
            }
        }
        return sum;
    }
    public void isHaveChuanDish() {       //判断是否具有川菜
        if (getChuanAllNum() == 0)
            return;
        else {
            System.out.print(" 川菜 " + getChuanAllNum());
            int num = (int) (1.0 * getChuanAllTaste() / getChuanAllNum() + 0.5);
            switch (num) {
                case 0: System.out.print(" 不辣");break;
                case 1: System.out.print(" 微辣");break;
                case 2: System.out.print(" 稍辣");break;
                case 3: System.out.print(" 辣");break;
                case 4: System.out.print(" 很辣");break;
                case 5: System.out.print(" 爆辣");break;
            }
        }
    }
    public void isHaveJinDish(){       //判断是否具有晋菜
        if(getJinAllNum()==0)
            return;
        else {
            System.out.print(" 晋菜 " + getJinAllNum());
            int num = (int) (1.0 * getJinAllTaste() / getJinAllNum() + 0.5);
            switch (num) {
                case 0: System.out.print(" 不酸");break;
                case 1: System.out.print(" 微酸");break;
                case 2: System.out.print(" 稍酸");break;
                case 3: System.out.print(" 酸");break;
                case 4: System.out.print(" 很酸");break;
//                case 5: System.out.print(" 爆");break;
            }
        }
    }
    public void isHaveZheDish(){       //判断是否具有浙菜
        if(getZheAllNum()==0)
            return;
        else {
            System.out.print(" 浙菜 " +getZheAllNum());
            int num =  (int) (1.0 * getZheAllTaste() / getZheAllNum() + 0.50);
            // System.out.println(" tatse: " + num);
            switch (num) {
                case 0: System.out.print(" 不甜");break;
                case 1: System.out.print(" 微甜");break;
                case 2: System.out.print(" 稍甜");break;
                case 3: System.out.print(" 甜");break;
//                case 4: System.out.print(" 很酸");break;
//                case 5: System.out.print(" 爆");break;
            }
        }
    }
    public void pf(){
        if(recordList.get(recordList.size()-1).getOtherTableNum()!=-1){
            recordList.get(recordList.size() - 1).pf(getTableNum());
        }
        else
            recordList.get(recordList.size() - 1).pf();
    }
    public void printf(){
        System.out.print("table "+getTableNum()+": "+getEarlyAllPrice()+" "+getAllPrice());
        if(getChuanAllNum()==0&&getJinAllNum()==0&&getZheAllNum()==0){
            System.out.print(" ");
        }
        isHaveChuanDish();
        isHaveJinDish();
        isHaveZheDish();
        System.out.println();
    }
    public boolean checkTasteValid(int taste,String s){             //检查口味是否在正常范围
        if(s.equals("川菜")&&(taste>5||taste<0)){
            System.out.println("spicy num out of range :"+taste);
            return false;
        }
        else if(s.equals("晋菜")&&(taste>4||taste<0)){
            System.out.println("acidity num out of range :"+taste);
            return false;
        }
        else if(s.equals("浙菜")&&(taste>3||taste<0)){
            System.out.println("sweetness num out of range :"+taste);
            return false;
        }
        return true;
    }

    // public void addPortion(){        //将份额和菜名相等的份数加起来
    //     for(int i = 0;i<recordList.size();i++)
    //         for(int j = 0;j<recordList.size();j++){
    //             if(!recordList.get(i).isDelete()&&recordList.get(i).isDelete()&&
    //                     recordList.get(i).getDish().getDishName().equals(recordList.get(j).getDish().getDishName())
    //                     &&recordList.get(i).getPortion()==recordList.get(j).getPortion()) {
    //                  recordList.get(i).setNum(recordList.get(i).getNum() +recordList.get(j).getNum());
    //                 recordList.get(j).setDelete(true);
    //             }
    //         }
    // }
}

class OtherRecord extends AbstractRecord{
    public boolean checkTaste(){       //检查口味值是否在范围内
        return false;
    }

    public OtherRecord(int recordNum, int num, int portion, int taste, AbstractDish dish, int otherTableNum) {
        super(recordNum, num, portion, taste, dish, otherTableNum);
    }

    public OtherRecord() {
    }

    @Override
    public void pf() {

    }

    @Override
    public void pf(int orderMum) {
        System.out.println(getRecordNum()+" table "+orderMum+" pay for table "+getOtherTableNum()+" "+getTotalPrice());
    }
}

class Record extends AbstractRecord{     //本桌菜
    public Record() {
    }
    @Override
    public void pf() {       //输出
        System.out.println(getRecordNum()+" "+getDish().getDishName()+" "+getDish().getPrice(getPortion(),getNum()));
    }

    @Override
    public void pf(int orderNum) {

    }

    public Record(int recordNum, int num, int portion, AbstractDish dish) {     //普通菜
        super(recordNum, num, portion, dish);
    }

    public Record(int recordNum, int num, int portion, int taste, AbstractDish dish) {      //特色菜
        super(recordNum, num, portion, taste, dish);
    }
}

class WorkTime {
//    final int [][] workDate = {{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
    static final LocalTime amtime = LocalTime.of(10, 29,59);     //周一到周五的上午营业时间
    static final LocalTime amtime1 = LocalTime.of(14, 30,1);
    static final LocalTime pmtime = LocalTime.of(16,59,59);      //周一到周五的晚上营业时间
    static final LocalTime pmtime1 = LocalTime.of(20, 30,1);
    static final LocalTime time1 = LocalTime.of(9, 29,59);       //周末的营业时间段
    static final LocalTime time = LocalTime.of(21,30,1);
    final LocalDate workDate1 = LocalDate.of(2022,1,1);
    final LocalDate workDate2 = LocalDate.of(2023,12, 31);
    public static boolean checkIsWorkTime(LocalDate tableDate,LocalTime tableTime){
        int num = tableDate.getDayOfWeek().getValue();      //获得星期几
        if(num>0&&num<6) {
            if(amtime.isBefore(tableTime)&&amtime1.isAfter(tableTime)||
                    pmtime.isBefore(tableTime)&&pmtime1.isAfter(tableTime)) {
                return true;
            }
        }
        else {
            if(time1.isBefore(tableTime)&&time.isAfter(tableTime))
                return true;
            else if(time1.isBefore(tableTime)&&tableTime.getMinute()==30&&tableTime.getSecond()==0)
                return true;
        }
//        System.out.println("table "+getTableNum()+" out of opening hours");
        return false;
    }
    public static int getDiscount(LocalDate tableDate,LocalTime tableTime){
        int num = tableDate.getDayOfWeek().getValue();
        if(num>0&&num<6) {
            if(amtime.isBefore(tableTime)&&amtime1.isAfter(tableTime))        //上午折扣
                return 6;
            if(pmtime.isBefore(tableTime)&&pmtime1.isAfter(tableTime)) {        //下午折扣
                return 8;
            }
        }
        return 10;        //周日的折扣
    }
    public static boolean checkOrderTime(String s){    //检查订单时间是否合法
        String validTime = "[0-9]{0,}";
        String []str = s.split("/");
        for(String str1:str){
            if(!str1.matches(validTime))
                return false;
        }
        int hours = Integer.parseInt(str[0]);
        int minutes = Integer.parseInt(str[1]);
        int seconds = Integer.parseInt(str[2]);
        if(hours>24||hours<0||minutes>60||minutes<0||seconds>60||seconds<0)
            return false;
        return true;
    }

    public static boolean checkOrderDate(String s){        //检查订单日期
        final int[][] mon_maxnum = {{31,28,31,30,31,30,31,31,30,31,30,31},
                {31,29,31,30,31,30,31,31,30,31,30,31}};
        String validDate = "[0-9]{0,}";
        String []str = s.split("/");
        for(String str1:str){
            if(!str1.matches(validDate))
                return false;
        }
        int year = Integer.parseInt(str[0]);
        int month = Integer.parseInt(str[1]);
        int day = Integer.parseInt(str[2]);
        int num = 0;        //0不是闰年,1是闰年
        if(isLeapYear(year))     //判断是否是闰年
            num = 1;
        if(month>12||month<=0||day>mon_maxnum[num][month-1]||day<=0)
            return false;
        return true;
    }
    public static boolean isLeapYear(int year){        //判断是否是闰年
        return (year%4==0&&year%100!=0)||year%400==0;
    }
}

class ZheDish extends AbstractDish{
    public ZheDish() {
    }

//    public ZheDish(int unit_price, String dishName) {
//        super(unit_price, dishName);
//    }

    public ZheDish(int unit_price, String dishName, String dishClass) {
        super(unit_price, dishName, dishClass);
    }

    @Override
    public int getPrice(int portion,int num){       //portion 是份额,num是份数
        int sum;        //总价
        if(portion==1)
            sum = getUnit_price() * num;
        else if(portion==2)
            sum = (int)(getUnit_price() * 1.5 + 0.5) * num;
        else
            sum = getUnit_price() * num * 2;
        return sum;
    }

    @Override
    public boolean checkTaste(int taste) {
        if(taste<4&&taste>=0)
            return true;
        System.out.println("sweetness num out of range :"+taste);
        return false;
    }
}

 (2)题目集8(课程成绩统计程序-1

这个题目在某些方面来说,与前面的题目比较相似,都是差不多的结构,只是实现的方式不同。来说说这个题目有哪些坑:

1、看题目描述

题目说班级平均分是相对于课程而言,而不是想对于在班级里面的人算平均分,也就是说最后计算班级平均分的时候是班级上所有的人的课程成绩相加 / 课程成绩的数量,不是我们日常理解的那种平均分。

2、看题目的描述:

但在实际的输出当中并不是这样输出的,而是   课程名称+英文空格+"does not exist"

3、看题目的描述:

这个在测试点当中是存在的,需要特别的判断一下,这些如果错误的话就都是输出  "wrong format",实际的输出过程中。

(3)题目集9(统计Java程序中关键词的出现次数)

对于这个题目如果你的正则表达式用对了的话就是只有一个需要注意的点,就是=null这种情况,目测是不需要将它判定为关键字,所以就在将源码的=号换成某个字符就行,在最后进行筛选判断,推荐使用replaceAll这个函数,将所有非字母换成空格,这样就可以拆分成单词进行判断。注释之类的在上文已经说过,不这里就不过多赘述。这里有一个输出方法比较奇特,之前都没有使用过:

 for (Map.Entry<String, Integer> entry : keywordsMap.entrySet()) {      //关键词输出
               System.out.println(entry.getValue() + "\t" + entry.getKey());
          }

看下测试效果图:

代  码


点击展开
 import java.util.*;
public class Main {
     private static Set<String> keySet = new HashSet<>(Arrays.asList("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"));          //关键字集合
     private static final Map<String,Integer> keywordsMap = new TreeMap<>();         //map
    
     public static void main(String[] args){
          Scanner in = new Scanner(System.in);
          StringBuffer codes = new StringBuffer();          //源码
          String line;                                    //一行一行读入
          while (!(line = in.nextLine()).equals("exit")) {        //读入
               codes.append(line).append("\n");
          }
          if (codes.length()==0) {                       //情况为空
               System.out.println("Wrong Format");
               return;
          }
          codes = deleteString(codes);                   //去掉字符串
          codes = codes.replace(0,codes.length()-1,codes.toString().replaceAll("\\/\\*[\\s\\S]*?\\*\\/", " "));//删除多行注释
          String[] codeLines = codes.toString().split("\n");     //分行
          for(String s:codeLines){                       //遍历所有行
               s = deleteComments(s);                    //删除行注释
               s = removeOtherChar(s);                    //删除其它字符
               String[] words = s.split(" ");            //单词切割
               for(String word:words){
                    if(keySet.contains(word)){            //判断是否是关键字
                         keywordsMap.put(word, keywordsMap.getOrDefault(word, 0) + 1);
                    }
               }
          }
          if (keywordsMap.isEmpty()) {                   //当前无关键词
               System.out.println();
               return;
          }
          for (Map.Entry<String, Integer> entry : keywordsMap.entrySet()) {      //关键词输出
               System.out.println(entry.getValue() + "\t" + entry.getKey());
          }
     }
    
     public static String deleteComments(String s){       //删除行注释
          return  s.replaceAll("//.*","");
     }
    
     public static StringBuffer deleteString(StringBuffer str){    //删掉字符串
          return str.replace(0,str.length()-1,str.toString().replaceAll("\".*?\"", " "));
     }

     public static String removeOtherChar(String s){            //删除其它字符       
          s = s.replaceAll("[\"\\-+><!:\\/*%&=]","w");        //特殊字符特殊处理防止出现多余
          return s.replaceAll("[^a-zA-Z]", " ");             
     }
}

使用map和set确实可以快速解决问题,大大缩小代码数量。

(4)题目集10(课程成绩统计程序-2)

这个程序是之前的课程成绩统计程序-2的衍生题目,加了实验课和实验成绩,基本套路都差不多,数据的正常处理,错误情况的判断。当时在写这个题目的时候第一次提交还有三个测试点没有过:

经过筛查发现,是因为我使用了map储存课程信息,然后map是没有重复的关键索引的,导致会不断地更新课程信息,而不是忽略已经重复的课程,这一点需要特别注意一下。

代  码

点击展开
 import java.text.Collator;
import java.util.Locale;
import java.util.ArrayList;
import java.util.*;
abstract class AbstractCourse implements Comparable<AbstractCourse>{
    private String courseID;
    private Collator collator = Collator.getInstance(Locale.CHINA);     //中文比较排序器

    public AbstractCourse(String courseID) {
        this.courseID = courseID;
    }

    public String getCourseID() {
        return courseID;
    }

    //检查课程的合法性
    public static boolean checkCourse(String s){
        String str[] = s.split(" ");
        if(str[0].length()>10)
            return false;
        if(str.length==2&&str[1].equals("必修"))
            return true;
        else if(str.length==3)
            return str[1].equals("必修") && str[2].equals("考试") || str[1].equals("选修")
                    && (str[2].equals("考试") || str[2].equals("考察"))||str[1].equals("实验")&&str[2].equals("实验");
        return false;
    }

    //比较函数,实现中文顺序
    @Override
    public int compareTo(AbstractCourse o) {
        return collator.compare(this.courseID,o.getCourseID());
    }
    public abstract String getStudyStyle();   //获得课程学习方式
    public abstract String getAssessStyle();  //获得课程考核方式
}

abstract class AbstractScore {   //抽象分数类
    private ArrayList<Integer> scores = new ArrayList<>();
    public AbstractScore() {
        super();
    }

    public ArrayList<Integer> getScores() {
        return scores;
    }

    public abstract int getGrade();
    public void addScores(String s) {
        String[] str = s.split(" ");
        for(String s1:str)
            getScores().add(Integer.parseInt(s1));
    }
    public static boolean checkScore(String s){     //检查分数格式是否合法
        String rightNum = "[0-9]{0,}";
        if(!s.matches(rightNum))
            return false;
        else {
            int scoreNum = Integer.parseInt(s);
            if(scoreNum<0||scoreNum>100)
                return false;
        }
        return true;
    }
}

class Agent {
    private Map<String,AbstractCourse> coursesMap = new HashMap<>();      //所有课程集合
    private ArrayList<SelectCourse> selectCourses = new ArrayList<>();  //所有成绩信息
    private Map<String,Class> classesMap = new HashMap<>();       //所有班级
//    public Map<String,Student> students = new HashMap<>();     //所有学生
    public void start(){
        //数据读入
        String rightNum = "[0-9]*";
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        //数据读入课程信息读入
        while(!s.split(" ")[0].matches(rightNum)&&!s.equals("end")){
            String[] str = s.split(" ");
            if(AbstractCourse.checkCourse(s))   //检查合法性并添加进入课程集合
                addToCourses(s);
            else {      //格式错误原因检查
                if((str.length==3&&str[1].equals("必修")&&str[2].equals("考察")||
                        !str[1].equals("实验")&&str[2].equals("实验"))&&str[0].length()<=10)
                    System.out.println(str[0]+" : course type & access mode mismatch");
                else
                    System.out.println("wrong format");
            }
            s = in.nextLine();
        }

        //选课成绩信息读入
        while(!s.equals("end")){
            String[] str = s.split(" ");
            if(SelectCourse.checkSelectCourse(s)){     //检查数据合法性
                if(searchSelectCourse(str[0],str[2])!=null){
                    s = in.nextLine();
                    continue;
                }
                if(checkSelectRecord(s))        //选课信息如果成绩正确
                    addSelectCourses(s);
                else        //没有成绩就直接加空
                    selectCourses.add(new SelectCourse(new Student(str[0],str[1])));
            }else
                System.out.println("wrong format");
            s = in.nextLine();
        }

        //数据处理
        studentToClass();   //遍历选课信息将学生添加到班级中
        printStudentGrade();//输出学生成绩信息
        printCourseScore(); //输出课程成绩信息
        printClassGrade();  //输出班级成绩信息
    }

    //遍历选课信息将学生添加到班级中
    public void studentToClass(){
        for(SelectCourse selectCourse : selectCourses){
            String cl = selectCourse.getStudent().getId().substring(0,6);       //班级号
            //班级不存在情况
            if(!classesMap.containsKey(cl)) {
                //添加班级
                classesMap.put(cl,new Class(cl));
                //将学生添加到班级
                classesMap.get(cl).addStudent(selectCourse.getStudent());
            }
            //班级存在且学生不在该班级直接加
            else if(classesMap.get(cl).searchStudent(selectCourse.getStudent().getId())==null){
                classesMap.get(cl).addStudent(selectCourse.getStudent());
            }
        }
    }

    //遍历学生输出学生的平均成绩
    public void printStudentGrade() {
        ArrayList<String> classes = new ArrayList<>(classesMap.keySet());
        Collections.sort(classes);
        for (String s:classes) {
            Collections.sort(classesMap.get(s).getStudents()); //对班上学生排序
            for (Student student : classesMap.get(s).getStudents()) {
                int sum = 0;
                int count = 0;  //计算学生所修课程数量
                for (SelectCourse selectCourse : selectCourses) {
                    if (selectCourse.getStudent().getId().equals(student.getId())) {
                        if (selectCourse.getCourse() == null)
                            continue;
                        sum += selectCourse.getScore().getGrade();
                        count++;
                    }
                }
                if (count == 0) {
                    System.out.println(student.getId() + ' ' + student.getName() + " did not take any exams");
                }
                else {
                    System.out.println(student.getId() + ' ' + student.getName() + ' ' + (sum / count));
                }
            }
        }
    }

    //输出班级的平均成绩
    public void printClassGrade(){
        ArrayList<String> classes = new ArrayList<>(classesMap.keySet());
        Collections.sort(classes);
        for(String s:classes){      //遍历班级输出班级的平均成绩
            int sum = 0;    //成绩总和
            int count = 0;  //记录班级学生所修的课程数量
            for(Student student:classesMap.get(s).getStudents()){
               for(SelectCourse selectCourse:selectCourses){
                   if(selectCourse.getStudent().getId().equals(student.getId())){
                       if(selectCourse.getCourse()==null)
                           continue;
                       sum+=selectCourse.getScore().getGrade();
                       count++;
                   }
               }
            }
            if(count==0)
                System.out.println(classesMap.get(s).getClassId()+" has no grades yet");
            else
                System.out.println(classesMap.get(s).getClassId()+' '+ sum/count);
        }
    }

    //输出课程的平均成绩
    public void printCourseScore(){
        //对课程进行排序
        ArrayList<String> courses = new ArrayList<>(coursesMap.keySet());
        Collections.sort(courses);
        for(String s:courses){
            int sum1 = 0,sum2 = 0,sum3 = 0,count = 0;   //分别记录期中成绩,期末成绩,总成绩,人数计数器
            for(SelectCourse selectCourse:selectCourses){
                if(selectCourse.getCourse()==null)      //课程为空跳过
                    continue;
                if(selectCourse.getCourse().getCourseID().equals(coursesMap.get(s).getCourseID())){
                    count++;
                    if(coursesMap.get(s).getAssessStyle().equals("考试")){
                        sum1+=selectCourse.getScore().getScores().get(0);//期中
                        sum2+=selectCourse.getScore().getScores().get(1);//期末
                    }   //考察和实验成绩的计算
                    sum3+=selectCourse.getScore().getGrade();       //总评
                }
            }
            //课程没有成绩
            if(count==0) {
                System.out.println(s + " " + "has no grades yet");
                continue;
            }
            //计算平均分
            sum1 = sum1/count;
            sum2 = sum2/count;
            sum3 = sum3/count;
            if(coursesMap.get(s).getAssessStyle().equals("考试"))
                System.out.println(coursesMap.get(s).getCourseID()+' '+sum1+" "+sum2+' '+sum3);
            else if(coursesMap.get(s).getAssessStyle().equals("考察"))
                System.out.println(coursesMap.get(s).getCourseID()+' '+sum3+' '+sum3);
            else
                System.out.println(coursesMap.get(s).getCourseID()+' '+sum3);
        }
    }

    //增加选课信息
    public void addSelectCourses(String s){
        String[] str = s.split(" ");
        Student student = new Student(str[0],str[1]);
        AbstractCourse course = coursesMap.get(str[2]);
        AbstractScore score;
        if(coursesMap.get(str[2]).getAssessStyle().equals("考试"))
            score = new TestScore();
        else if(coursesMap.get(str[2]).getAssessStyle().equals("考察"))
            score = new CheckScore();
        else
            score = new LabScore();
        if(coursesMap.get(str[2]).getAssessStyle().equals("实验"))//实验情况另外对待
            score.addScores(s.substring(s.indexOf(str[4])));
        else
            score.addScores(s.substring(s.indexOf(str[3])));
        selectCourses.add(new SelectCourse(student,course,score));      //添加
    }

    public boolean checkSelectRecord(String s){     //检查课程信息是否匹配
        String str[] = s.split(" ");
        if(!coursesMap.containsKey(str[2])) {   //检查是否含有该课程
            System.out.println(str[2] + " does not exist");
            return false;
        }
        //对成绩和课程信息的检查
        int len = str.length;    //输入信息的长度
        if(coursesMap.get(str[2]).getAssessStyle().equals("考试")&&len!=5||
                coursesMap.get(str[2]).getAssessStyle().equals("考察")&&len!=4){
            System.out.println(str[0]+' '+str[1]+" : access mode mismatch");
            return false;
        }
        //实验成绩的特殊判断
        if(coursesMap.get(str[2]).getAssessStyle().equals("实验")){
            int num = Integer.parseInt(str[3]); //实验次数
            if(len!=4+num){
                System.out.println(str[0]+' '+str[1]+" : access mode mismatch");
                return false;
            }
        }
        return true;
    }

    //查找是否存在该课程成绩
    public SelectCourse searchSelectCourse(String s1,String s2){
        for(SelectCourse selectCourse:selectCourses){
            if(selectCourse.getCourse()==null)      //跳过没有课程的选课信息
                return null;
            if(selectCourse.getStudent().getId().equals(s1)&&
                    selectCourse.getCourse().getCourseID().equals(s2))      //比较学生和课程
                return selectCourse;
        }
        return null;
    }
    //将课程信息加入到课程当中
    public void addToCourses(String s){
        String[] str = s.split(" ");
        if(coursesMap.containsKey(str[0]))
            return;
        AbstractCourse course = null;
        if(str[1].equals("必修")){        //必修课
            course = new CompulsoryCourse(str[0]);
        }
        if(str[1].equals("选修")){
            course = new ElectiveCourse(str[0],str[2]);
        }
        if(str[1].equals("实验")){
            course = new LabCourse(str[0]);
        }
        coursesMap.put(str[0],course);
    }
}

class CheckScore extends AbstractScore{//考察分数

    //获得考察分数,考察只有一个成绩
    @Override
    public int getGrade() {
        int sum = 0;
        if(getScores().size()==0)
            return -1;
        for(Integer num:getScores())
            sum += num;
        return sum/getScores().size();
    }
}

class Class implements Comparable<Class>{
    private ArrayList<Student> students = new ArrayList<>();    //学生列表
    private String classId;     //学号

    public String getClassId() {
        return classId;
    }


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

    public ArrayList<Student> getStudents() {
        return students;
    }

    public void addStudent(Student student){        //添加学生
        students.add(student);
    }
    public Student searchStudent(String s){     //查找学生
        for(Student student:students){
            if(student.getId().equals(s))
                return student;
        }
        return null;
    }
    @Override
    public int compareTo(Class o) {     //比较函数
        return this.classId.compareTo(o.classId);
    }
}

class CompulsoryCourse extends AbstractCourse{
    public CompulsoryCourse(String courseID) {
        super(courseID);
    }
    //返回课程性质
    @Override
    public String getStudyStyle() {
        return "必修";
    }
    //返回课程考核方式
    @Override
    public String getAssessStyle() {
        return "考试";
    }
}
class ElectiveCourse extends AbstractCourse{
    //考核方式
    private String assessStyle;
    public ElectiveCourse(String courseID,String assessStyle) {
        super(courseID);
        this.assessStyle = assessStyle;
    }
    //获得课程学习方式
    @Override
    public String getStudyStyle() {
        return "选修";
    }
    //获得考核方式
    @Override
    public String getAssessStyle() {
        return assessStyle;
    }
}

class LabCourse extends AbstractCourse{      //实验课

    public LabCourse(String courseID) {
        super(courseID);
    }
    //获得课程学习方式
    @Override
    public String getStudyStyle() {
        return "实验";
    }
    //获得课程考核方式
    @Override
    public String getAssessStyle() {
        return "实验";
    }
}
class LabScore extends AbstractScore{        //实验成绩
    //获得实验成绩
    @Override
    public int getGrade() {
        int sum = 0;
        if(getScores().size()==0)
            return -1;
        for(Integer num:getScores())
            sum += num;
        return sum/getScores().size();
    }
}
public class Main {
    public static void main(String[] args){
        Agent agent = new Agent();
        agent.start();
    }
}

class SelectCourse {
    private Student student;
    private AbstractCourse course;
    private AbstractScore score;

    public SelectCourse(Student student) {
        this.student = student;
    }

    public SelectCourse() {
    }

    public SelectCourse(Student student, AbstractCourse course, AbstractScore score) {
        this.student = student;
        this.course = course;
        this.score = score;
    }

    public Student getStudent() {
        return student;
    }

    public AbstractCourse getCourse() {
        return course;
    }

    public AbstractScore getScore() {
        return score;
    }

    public static boolean checkSelectCourse(String s){     //检查选课信息
        String str[] = s.split(" ");
        String rightNum = "[0-9]{0,}";
        if(str.length<4)       //格式检查
            return false;
        if(str[1].length()>10)  //名字长度
            return false;
        if(!str[0].matches(rightNum)||str[0].length()!=8)  //学号检查
            return false;
        else if(str.length==4&&!(str[3].matches(rightNum)&&
                AbstractScore.checkScore(str[3])))
            return false;
        else if(str.length==5&&!(str[3].matches(rightNum)&&str[4].matches(rightNum)
        &&AbstractScore.checkScore(str[3])&&AbstractScore.checkScore(str[4])))
            return false;
        if(str.length>5){       //实验成绩检查
            for(int i=3;i< str.length;i++)
                if(!str[i].matches(rightNum)||!AbstractScore.checkScore(str[i]))
                    return false;
            int num = Integer.parseInt(str[3]);//实验次数
            if(num<4||num>9)    //次数不达标
                return false;
        }
        return true;
    }
}

class Student implements Comparable<Student>{    //学生类
    private String id;          //学号
    private String name;        //名字
    public Student(String id,String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Student o) {       //比较函数
        return this.id.compareTo(o.id);
    }
}

class TestScore extends AbstractScore{//考试分数
    @Override
    public int getGrade() {         //获得当前考试成绩,考试有期中期末成绩占比3 7
        int sum = 0;
        if(getScores().size()==0)
            return -1;
        return (int) (getScores().get(0)*0.3+getScores().get(1)*0.7);
    }
}

(5)题目集11( 课程成绩统计程序-3

这个题目依旧是上一个题目的衍生版本,从题目难度来讲,不算太难,需要注意的是所有的成绩都是有比重的,考试方式的成绩不再是固定的0.3 0.7了,而是可以手动输入,至于考察成绩就默认为1。就是有一个测试点很诡异,来一起看下这个测试点是哪个测试点:

这个测试点我足足测试了有将近50-60次左右,可以概括为以下几个方面:重复课程输入,成绩信息引用重复错误课程信息,重复成绩信息,重复错误成绩信息,更换成绩算法。但是都失败了,于是转变思路,在前面输入课程比重的时候出现过 0.2+0.2+0.3+0.2+0.1 是 0.9999999 的情况,就意识到可能是实数数据类型会丢失精度,导致最后结果出现问题。于是就往最后取结果的时候加上了0.0000001,这样就不会干扰正常的数据,同时也能改变由于精度问题出现的问题。结果确实是对的。

代  码
点击展开
 import java.text.Collator;
import java.util.Locale;
import java.util.*;
import java.util.ArrayList;
abstract class AbstractCourse implements Comparable<AbstractCourse>{
    private String courseID;        //课程名
    private Collator collator = Collator.getInstance(Locale.CHINA);     //中文比较排序器
    private final double[] weight;      //课程考核数量


    public AbstractCourse(String courseID,double m[]) {
        this.courseID = courseID;
        this.weight = m;
    }

    public String getCourseID() {
        return courseID;
    }
    //获得当前课程的考核次数
    public double[] getWeight() {
        return weight;
    }

    //检查课程的合法性
    public static boolean checkCourse(String s){
       String rightNum = "[0-9.]*";
        String [] str= s.split(" ");
        //课程名称长度检查
        if(str[0].length()>10||str.length<3||str.length==4)
            return false;
        else if(str.length==3)
            return str[1].equals("选修")&&str[2].equals("考察");
        //必修课的考察
        else if(str.length==5){
            if(!str[2].equals("考试"))
                return false;
            //必修课程的权重格式检查
            for(int i=4;i<str.length;i++)
                if(!str[i].matches(rightNum))
                    return false;
            //必修权重之和检查
            return checkCourseWeight(s.substring(s.indexOf(str[3])));
        }
        //实验课的格式检查
        else if(str[1].equals("实验")&&str[2].equals("实验")&&str[3].matches(rightNum)){
            int num = Integer.parseInt(str[3]);
            if(num<4||num>9)
                return false;
            if(str.length!=num+4)
                return false;
            for(int i=4;i<str.length;i++)
                if(!str[i].matches(rightNum))
                    return false;
            //课程权重相加判断
            return checkCourseWeight(s.substring(s.indexOf(str[4])));
        }
        return false;
    }
    //检查课程权重不满足1
    public static boolean checkCourseWeight(String s){
        String[] str = s.split(" ");
        int sum = 0;
        for(int i=0;i<str.length;i++){
            sum += (int)(Double.parseDouble(str[i])*10);
        }
//        return Math.abs(sum-1.0)<0.0000001;
        return sum==10;
    }
    //比较函数,实现中文顺序
    @Override
    public int compareTo(AbstractCourse o) {
        return collator.compare(this.courseID,o.getCourseID());
    }
}

class Agent {
    private Map<String,AbstractCourse> coursesMap = new HashMap<>();      //所有课程集合
    private ArrayList<SelectCourse> selectCourses = new ArrayList<>();  //所有成绩信息
    private Map<String,Class> classesMap = new HashMap<>();       //所有班级
    public void start(){
        //数据读入
        String rightNum = "[0-9]*";
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        //数据读入课程信息读入
         while(!s.split(" ")[0].matches("[0-9]{8,}")&&!s.equals("end")){
             //空行
             if(s.equals("")){
                s = in.nextLine();
                System.out.println("wrong format");
                continue;
            }
            String [] str = s.split(" ");
            if(coursesMap.containsKey(str[0])){
                // checkAgainCourse(s);
                s = in.nextLine();
                continue;
            }
            if(AbstractCourse.checkCourse(s))   //检查合法性并添加进入课程集合
                addToCourses(s);
            else {      //格式错误原因检查
                checkCourseError(s);
            }
            s = in.nextLine();
        }

        //选课成绩信息读入
        while(!s.equals("end")){
            //空行
            if(s.equals("")){
                s = in.nextLine();
                System.out.println("wrong format");
                continue;
            }
            String[] str = s.split(" ");
            //该选课信息已经存在
            if(searchSelectCourse(str[0],str[2],str.length)!=null){
                    s = in.nextLine();
                    continue;
            }
            if(SelectCourse.checkSelectCourse(s)){     //检查数据合法性
                if(checkSelectRecord(s))        //选课信息如果成绩正确
                    addSelectCourses(s);
                else        //没有成绩就直接加空
                    selectCourses.add(new SelectCourse(new Student(str[0],str[1])));
            }else
                System.out.println("wrong format");
            s = in.nextLine();
        }

        //数据处理
        studentToClass();   //遍历选课信息将学生添加到班级中
        printStudentGrade();//输出学生成绩信息
        printCourseScore(); //输出课程成绩信息
        printClassGrade();  //输出班级成绩信息
    }

    //遍历选课信息将学生添加到班级中
    public void studentToClass(){
        for(SelectCourse selectCourse : selectCourses){
            String cl = selectCourse.getStudent().getId().substring(0,6);       //班级号
            //班级不存在情况
            if(!classesMap.containsKey(cl)) {
                //添加班级
                classesMap.put(cl,new Class(cl));
                //将学生添加到班级
                classesMap.get(cl).addStudent(selectCourse.getStudent());
            }
            //班级存在且学生不在该班级直接加
            else if(classesMap.get(cl).searchStudent(selectCourse.getStudent().getId())==null){
                classesMap.get(cl).addStudent(selectCourse.getStudent());
            }
        }
    }

    //遍历学生输出学生的平均成绩
    public void printStudentGrade() {
        //将集合里面的班级转换成list进行排序,根据班级进行排序
        ArrayList<String> classes = new ArrayList<>(classesMap.keySet());
        Collections.sort(classes);
        //遍历班级
        for (String s:classes) {
            Collections.sort(classesMap.get(s).getStudents()); //对班上学生排序
            //遍历班上的学生
            for (Student student : classesMap.get(s).getStudents()) {
                int sum = 0;
                int count = 0;  //计算学生所修课程数量
                for (SelectCourse selectCourse : selectCourses) {
                    if (selectCourse.getStudent().getId().equals(student.getId())) {
                        if (selectCourse.getCourse() == null)
                            continue;
                        sum += selectCourse.getScore().getGrade();
                        count++;
                    }
                }
                if (count == 0) {
                    System.out.println(student.getId() + ' ' + student.getName() + " did not take any exams");
                }
                else {
                    System.out.println(student.getId() + ' ' + student.getName() + ' ' + (sum / count));
                }
            }
        }
    }

    //输出班级的平均成绩
    public void printClassGrade(){
        ArrayList<String> classes = new ArrayList<>(classesMap.keySet());
        Collections.sort(classes);
        for(String s:classes){      //遍历班级输出班级的平均成绩
            int sum = 0;    //成绩总和
            int count = 0;  //记录班级学生所修的课程数量
            for(Student student:classesMap.get(s).getStudents()){
                for(SelectCourse selectCourse:selectCourses){
                    if(selectCourse.getStudent().getId().equals(student.getId())){
                        if(selectCourse.getCourse()==null)
                            continue;
                        sum+=selectCourse.getScore().getGrade();
                        count++;
                    }
                }
            }
            //判断数量是否为零
            if(count==0)
                System.out.println(classesMap.get(s).getClassId()+" has no grades yet");
            else
                System.out.println(classesMap.get(s).getClassId()+' '+ sum/count);
        }
    }

    //输出课程的平均成绩
    public void printCourseScore(){
        //对课程进行排序
        ArrayList<String> courses = new ArrayList<>(coursesMap.keySet());
        Collections.sort(courses);
        for(String s:courses){
            int sum3 = 0,count = 0;   //分别记录期中成绩,期末成绩,总成绩,人数计数器
            for(SelectCourse selectCourse:selectCourses){
                if(selectCourse.getCourse()==null)      //课程为空跳过
                    continue;
                if(selectCourse.getCourse().getCourseID().equals(coursesMap.get(s).getCourseID())){
                    count++;
                    //总评成绩相加
                    sum3+=selectCourse.getScore().getGrade();
                }
            }
            //课程没有成绩
            if(count==0) {
                System.out.println( s+ " " + "has no grades yet");
                continue;
            }
            sum3 = sum3/count;
            System.out.println(coursesMap.get(s).getCourseID()+' '+sum3);
        }
    }

    //增加选课信息
    public void addSelectCourses(String s){
        String[] str = s.split(" ");
        Student student = new Student(str[0],str[1]);
        AbstractCourse course = coursesMap.get(str[2]);
        CourseScore score = new CourseScore(course.getWeight());
        score.addScores(s.substring(s.indexOf(str[2])+str[2].length()+1));
        //添加
        selectCourses.add(new SelectCourse(student,course,score));
    }

    public boolean checkSelectRecord(String s){     //检查课程信息是否匹配
        String str[] = s.split(" ");
        //检查是否含有该课程
        if(!coursesMap.containsKey(str[2])) {
            System.out.println(str[2] + " does not exist");
            return false;
        }
        //对成绩和课程信息的检查
        int len = str.length;    //输入信息的长度
        if(len!=coursesMap.get(str[2]).getWeight().length+3){
            System.out.println(str[0]+' '+str[1]+" : access mode mismatch");
            return false;
        }
        return true;
    }

    //查找是否存在该课程成绩
    public SelectCourse searchSelectCourse(String s1,String s2,int len){
        for(SelectCourse selectCourse:selectCourses){
            if(selectCourse.getCourse()==null)      //跳过没有课程的选课信息
                continue;
            if(selectCourse.getStudent().getId().equals(s1)&& selectCourse.getCourse().
                    getCourseID().equals(s2))      //比较学生和课程
                return selectCourse;
        }
        return null;
    }
    //将课程信息加入到课程当中
    public void addToCourses(String s){
        String[] str = s.split(" ");
        //检查是否包含该课程
        if(coursesMap.containsKey(str[0]))
            return;
        AbstractCourse course = null;
        if(str[1].equals("必修")){        //必修课
            course = new CompulsoryCourse(str[0],new double[]{Double.parseDouble(str[3]),Double.parseDouble(str[4])});
        }
        if(str[1].equals("选修")){
            if(str[2].equals("考试"))
                course = new ElectiveCourse(str[0],new double[]{Double.parseDouble(str[3]),Double.parseDouble(str[4])});
            else
                course = new ElectiveCourse(str[0],new double[]{1.0});
        }
        if(str[1].equals("实验")){
            double[] hn = new double[Integer.parseInt(str[3])];
            //转换成实数表示权重
            for(int i=4;i<str.length;i++){
                hn[i-4] = Double.parseDouble(str[i]);
            }
            course = new LabCourse(str[0],hn);
        }
        //放入课程集合
        coursesMap.put(str[0],course);
    }
    //课程信息错误筛查
    public void checkCourseError(String s){
        String[] str = s.split(" ");
        //各种必修选修组合错误检查
        if(str.length<=3){
            if(str.length==2&&!str[1].equals("必修"))
                System.out.println("wrong format");
            else if(str[1].equals("必修")&&!str[2].equals("考试"))
                System.out.println(str[0]+" : course type & access mode mismatch");
            else if(str[1].equals("选修")&&!str[2].equals("考试")&&!str[2].equals("考察"))
                System.out.println(str[0]+" : course type & access mode mismatch");
            else if(str[1].equals("实验")&&!str[2].equals("实验"))
                System.out.println(str[0]+" : course type & access mode mismatch");
            else
                System.out.println("wrong format");
        }
        //成绩权重数量不匹配和格式不正确
        else if(!str[3].matches("[0-9]+")||Integer.parseInt(str[3])<4||Integer.parseInt(str[3])>9)
            System.out.println("wrong format");
        else if(str.length!=Integer.parseInt(str[3])+4)
            System.out.println(str[0]+" : number of scores does not match");
        else if(str[1].equals("实验")&&!str[2].equals("实验")||str[2].equals("实验")&&!str[1].equals("实验"))
            System.out.println(str[0]+" : course type & access mode mismatch");
            //判断课程分值权重
        else if(Integer.parseInt(str[3])<4||Integer.parseInt(str[3])>9)
            System.out.println("wrong format");
        else if(str[2].equals("实验")&&!AbstractCourse.checkCourseWeight(s.substring(s.indexOf(str[4]))))
            System.out.println(str[0]+" : weight value error");
        else
            System.out.println("wrong format");
    }
    
}
//班级类
class Class implements Comparable<Class>{
    private ArrayList<Student> students = new ArrayList<>();    //学生列表
    private String classId;     //学号

    public String getClassId() {
        return classId;
    }


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

    public ArrayList<Student> getStudents() {
        return students;
    }

    public void addStudent(Student student){        //添加学生
        students.add(student);
    }
    public Student searchStudent(String s){     //查找学生
        for(Student student:students){
            if(student.getId().equals(s))
                return student;
        }
        return null;
    }

    @Override
    public int compareTo(Class o) {     //比较函数
        return this.classId.compareTo(o.classId);
    }
}

//必修课
class CompulsoryCourse extends AbstractCourse{
    public CompulsoryCourse(String courseID, double[] doubles) {
        super(courseID, doubles);
    }
}
//考察分数
class CourseScore {
    private SubsystemScore subsystemScore;

    public CourseScore(double m[]) {
        this.subsystemScore = new SubsystemScore(m);
    }

    public void addScores(String s) {
        subsystemScore.addToScore(s);
    }
    public static boolean checkScore(String s){     //检查分数格式是否合法
        //数字匹配
        String rightNum = "[0-9]{0,}";
        if(!s.matches(rightNum))
            return false;
        else {
            int scoreNum = Integer.parseInt(s);
            if(scoreNum<0||scoreNum>100)
                return false;
        }
        return true;
    }
    //获得当前考试成绩
    public int getGrade() {
        return subsystemScore.getTotalScore();
    }
}
//选修课
class ElectiveCourse extends AbstractCourse{     
    public ElectiveCourse(String courseID,double m[]) {
        super(courseID,m);
    }
}
//实验课
class LabCourse extends AbstractCourse{      

    public LabCourse(String courseID,double m[]) {
        super(courseID,m);
    }
}

public class Main {
    public static void main(String[] args){
        Agent agent = new Agent();
        agent.start();
    }
}
//选课信息类
class SelectCourse {
    private Student student;        //学生
    private AbstractCourse course;    //课程
    private CourseScore score;        //课程分数

    public SelectCourse(Student student) {
        this.student = student;
    }

    public SelectCourse() {
    }

    public SelectCourse(Student student, AbstractCourse course, CourseScore score) {
        this.student = student;
        this.course = course;
        this.score = score;
    }

    public Student getStudent() {
        return student;
    }


    public AbstractCourse getCourse() {
        return course;
    }


    public CourseScore getScore() {
        return score;
    }

    public static boolean checkSelectCourse(String s){     //检查选课信息
        String str[] = s.split(" ");
        String rightNum = "[0-9]*";
        if(str.length<3)       //格式检查
            return false;
        if(str[1].length()>10)  //名字长度
            return false;
        if(!str[0].matches(rightNum)||str[0].length()!=8)  //学号检查
            return false;
        else if(str.length==4&&!(str[3].matches(rightNum)&&
                CourseScore.checkScore(str[3])))
            return false;
        else if(str.length==5&&!(str[3].matches(rightNum)&&str[4].matches(rightNum)
        &&CourseScore.checkScore(str[3])&&CourseScore.checkScore(str[4])))
            return false;
        if(str.length>5){       //实验成绩检查
            //数据格式
            for(int i=3;i< str.length;i++)
                if(!str[i].matches(rightNum)||!CourseScore.checkScore(str[i]))
                    return false;
            //次数
            return true;
        }
        return true;
    }
}

class Student implements Comparable<Student>{    //学生类
    private String id;          //学号
    private String name;        //名字
    public Student(String id,String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Student o) {       //比较函数
        return this.id.compareTo(o.id);
    }
}

class SubsystemScore {       //分项成绩
    private int []scores;       //分数
    private double []weight;        //每次考试比重

    public SubsystemScore(double m[]) {
        this.weight = m;
        this.scores =new int [m.length];
    }
    //获得总成绩
    public int getTotalScore(){
        double sum = 0;
        for(int i=0;i<scores.length;i++){
            sum += weight[i]*scores[i];
        }
        return (int)(sum+0.00000001);
    }
    //检查成绩格式是否匹配
    public boolean checkScore(String s){
        String [] str = s.split(" ");
        return str.length!=weight.length;
    }
    //录入成绩
    public void addToScore(String s){
        String [] str = s.split(" ");
        for(int i=0;i<str.length;i++){
            scores[i] = Integer.parseInt(str[i]);
        }
    }
}

4、改进建议

在这部分主要是对相应题目的编码改进给出自己的见解,做到可持续改进。

对于菜单类的程序,经过这么多次的题目训练,已经对于一些套路比较熟悉了,首先重中之重的是拿到题目立马将题目看3遍,防止遗漏一些数据处理问题,再就是想好对于这题需要采用什么样的类间关系,好的类间关系可以节省一大部分的时间。充分考虑程序的可拓展性,这样能够减少后续代码修改所造成的麻烦,考虑到可拓展性就,就是里氏代换原则和继承与多态这方面比较重要。比如说成绩统计程序,如果采用继承关系,后续加入实验课的时候只需要改动实验信息输入和加入实验课程类就行,不需要对代码进行大改。如果是统计关键字的那种情况,由于所需要的代码数量比较少,可以不考虑那么深入,直接一个类就行。

对于这些题目,考虑的基本都是我们的耐心,不要看题目很长就放弃,实际上将这些问题进行分解后,再一步一步的解决他们事情就会变得简单。遇到测试点无法通过,需要静下心来思考题目所给的提示。要充分相信自己的判断。在编写这些题目时注意的问题在上部分就已经提出来了,这里不在过多赘述。如果要做到可持续改进的话需要在一些体现自己思路的代码部分书写注释,方便后续修改。

5、总结

在这部分,将对本阶段(10-16周)综合性总结,包括学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。

这阶段还是学到了挺多东西的,其中的翻转课堂等等课程形式我感觉十分的新颖,能够帮助我们学习javaFx的相关知识。还有最后的几节课所学的集合框架的内容,让我们受益匪浅。正则表达式,map,set,stack,队列等等集合框架对于我们来说都是十分有用的。这不仅仅是在帮助我们打基础,更让我们从题目,课程中获得更多知识,学到老师写代码的思路,再揉和自己的见解,变成自己的东西。如果老师能够下降一点点题目的难度,然后再加大题目的量就更完美了。

不足:在这一阶段的学习当中,我认为不能只拘泥于课程所学,还要将目光放在更宽广的领域,课程所学远远不足以让我们变得强大,还有就是代码的可读性需要研究一下,就目前写的代码来讲,确实是自己都有点难以理解,需要思考良久才能反映过来。在其他方面,我们也需要将课上所学知识运用到实处,不能局限于理论。

二、课程建议

首先对于课程进行一个简单的评价:经过这一个学期的学习,学到了许多东西,面对对象的编程思想,逐渐提高的编码速度等等。十几次的题目集训练,边讲边练的教学方法,能够帮助我们逐步解决难题,并巩固知识,培养解决问题的能力,提高我们应对挑战和解决问题的自信心。同时BOPPPS模式也是一种很好的教学模式,可以培养我们的自主学习和实践能力,并且可以消除我们的课堂厌倦感,活跃课堂气氛,比如翻转课堂,确实是学到了挺多知识。其它方面课程讲解和实践操作相结合做得相当不错,可以帮助我们更加深入地理解和掌握知识。

给点建议:通过这段时间的学习,好几次被题目集打击自信,个人认为应该加点基础题目的数量,这样的话做不出的话还可以巩固一下基本知识,像后面两次题目集就比较好,单纯是一个题目的话就有点片面了,要充分考虑到各个阶段层次的学生,还有就是对于那个学习通上面的慕课希望可以开放,有些人一旦没有注意就没有机会再看了,我认为这是比较大的损失。对于实验的话希望可以多设点关乎课程知识的使用的实验,比如农夫过河这类的问题,但不要一直都是这个例子,一直都做这方面的实验太过片面,基本套路不变的话对于学生解决问题的能力不能起到良好的培养效果。

posted @ 2023-06-24 21:42  nnhz  阅读(36)  评论(0)    收藏  举报