OOP第三次博客作业

发布时间 2023-06-27 20:26:54作者: eks++

前言:

第三阶段PTA的题目集主要围绕课程成绩统计程序的改进展开,共进行了三次题目集的迭代改进。在每次迭代中,题目集的重点和难度都有所增加。

第一次题目集侧重于类的继承、多态性的使用以及Comparable接口的应用。通过实现图形卡片分组的功能,我们需要熟练掌握类的继承和多态性的概念,并能够正确地使用Comparable接口对图形卡片进行排序和分组。

第二次题目集引入了HashMap和TreeMap的使用,我们需要使用这两个数据结构来统计Java程序中关键词的出现次数。此外,题目还要求使用正则表达式来精简代码。这一次迭代的难度相对较高,需要我们熟练掌握HashMap和TreeMap的使用方法,并且对正则表达式有一定的了解。

第三次题目集继续围绕课程成绩统计程序展开,但难度进一步增加。我们需要根据用户需求进行三次迭代改进,逐步增加代码量和功能的复杂度。这次迭代要求我们更加熟练地运用面向对象编程的思想和技巧,同时要求学生对用户需求进行精细化的分析和设计。

此外,由于题目集的内容也逐步深入,从简单的类继承和多态性的应用,到正则表达式的应用,再到面向对象编程的高级应用,难度逐渐加大。但通过这三次题目集的练习和实验指导书的提示,我的代码编写能力正在逐步提高,对面向对象编程的理解和应用也更加深入。

 

设计与分析:  

本次分析题目集中的部分题目,从简单到复杂,下面做简要分析。

 

一、图形卡片分组游戏

本次题目集分为两次迭代,第一次需要根据学生得到的卡片种类与数量,给出排序前和排序后的卡片顺序,同时给出所有卡片的面积之和;第二次输入各种卡片的相应参数,首先根据卡片类型将所有卡片进行分组(一个类型分为一组, 所以最多四组),然后能够对每组内的卡片根据面积值从大到小进行排序,同时求出该组内所有卡片的面积之和,最后求出每组卡片面积之和中的最大值。

以下为完整代码:

import java.util.ArrayList;
import java.util.TreeSet;
import java.util.Scanner;

public class Main {
    //在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接
    //使用Main.input.next…即可(避免踩坑)
    public static Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        int num = input.nextInt();
        if(num == 0){
            System.out.println("Wrong Format");
            return;
        }
        while (num != 0) {
            if (num < 0 || num > 4) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            list.add(num);
            num = input.nextInt();
        }
        DealCardList dealCardList = new DealCardList(list);
        if (!dealCardList.validate()) {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        dealCardList.showResult();
        input.close();
    }
}

class DealCardList {
    protected ArrayList<Card> cardList = new ArrayList<>();
    double[] shape = new double[4];//将各种图形的总面积放入这个数组中

    public DealCardList() {
    }

    //根据输入情况将图形存入列表中
    public DealCardList(ArrayList<Integer> list) {
        for (Integer integer : list) {
            switch (integer) {
                case 1://加入圆形
                    Card card1 = new Card(new Circle(Main.input.nextDouble()));
                    card1.getShape().setShapeName("Circle");
                    cardList.add(card1);
                    break;
                case 2://加入矩形
                    Card card2 = new Card(new Rectangle(Main.input.nextDouble(), Main.input.nextDouble()));
                    card2.getShape().setShapeName("Rectangle");
                    cardList.add(card2);
                    break;
                case 3: //加入三角形
                    Card card3 = new Card(new Triangle(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble()));
                    card3.getShape().setShapeName("Triangle");
                    cardList.add(card3);
                    break;
                case 4: //加入梯形
                    Card card4 = new Card(new Trapezoid(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble()));
                    card4.getShape().setShapeName("Trapezoid");
                    cardList.add(card4);
                    break;
                default:
                    break;
            }
        }
    }

    //判断输入的图形属性值是否非法
    public boolean validate() {
        for (Card card : cardList) {
            if (!card.getShape().validate()) return false;
        }
        return true;
    }

    //输出圆的数据并计算总面积
    public void circleArea() {
        shape[0] = 0;
        System.out.print("[");
        for (Card a : cardList) {
            if (a.getShape().getShapeName().equals("Circle")) {
                System.out.print(a.getShape());
                shape[0] = shape[0] + a.getShape().getArea();
            }
        }
        System.out.print("]");
    }

    //输出矩形的数据并计算总面积
    public void rectangleArea() {
        shape[1] = 0;
        System.out.print("[");
        for (Card a : cardList) {
            if (a.getShape().getShapeName().equals("Rectangle")) {
                System.out.print(a.getShape());
                shape[1] = shape[1] + a.getShape().getArea();
            }
        }
        System.out.print("]");
    }

    //输出三角形的数据并计算总面积
    public void triangleArea() {
        shape[2] = 0;
        System.out.print("[");
        for (Card a : cardList) {
            if (a.getShape().getShapeName().equals("Triangle")) {
                System.out.print(a.getShape());
                shape[2] = shape[2] + a.getShape().getArea();
            }
        }
        System.out.print("]");
    }

    //输出梯形的数据并计算总面积
    public void trapezoidArea() {
        shape[3] = 0;
        System.out.print("[");
        for (Card a : cardList) {
            if (a.getShape().getShapeName().equals("Trapezoid")) {
                System.out.print(a.getShape());
                shape[3] = shape[3] + a.getShape().getArea();
            }
        }
        System.out.print("]");
    }

    //圆的面积从大到小排序
    public void cardSort1() {
        TreeSet<Card> kp = new TreeSet<>(cardList);
        System.out.print("[");
        for (Card a : kp) {
            if (a.getShape().getShapeName().equals("Circle")) {
                System.out.print(a.getShape());
            }
        }
        System.out.print("]");
    }

    //矩形的面积从大到小排序
    public void cardSort2() {
        TreeSet<Card> kp = new TreeSet<>(cardList);
        System.out.print("[");
        for (Card a : kp) {
            if (a.getShape().getShapeName().equals("Rectangle")) {
                System.out.print(a.getShape());
            }
        }
        System.out.print("]");
    }

    //三角形的面积从大到小排序
    public void cardSort3() {
        TreeSet<Card> kp = new TreeSet<>(cardList);
        System.out.print("[");
        for (Card a : kp) {
            if (a.getShape().getShapeName().equals("Triangle")) {
                System.out.print(a.getShape());
            }
        }
        System.out.print("]");
    }

    //梯形的面积从大到小排序
    public void cardSort4() {
        TreeSet<Card> kp = new TreeSet<>(cardList);
        System.out.print("[");
        for (Card a : kp) {
            if (a.getShape().getShapeName().equals("Trapezoid")) {
                System.out.print(a.getShape());
            }
        }
        System.out.print("]");
    }

    //找出最大总面积
    public double getMax() {
        double max = 0;
        for (int i = 0; i < 4; i++) {
            if (max < shape[i]) max = shape[i];
        }
        return max;
    }

    //输出所有情况的结果
    public void showResult() {
        System.out.println("The original list:");//排序前的各图形类型及面积
        System.out.print("[");
        for (Card c : cardList) {
            System.out.print(c.getShape());
        }
        System.out.print("]");
        System.out.println();
        System.out.println("The Separated List:");//输出分组后的图形类型及面积
        circleArea();
        rectangleArea();
        triangleArea();
        trapezoidArea();
        System.out.println();
        System.out.println("The Separated sorted List:");//各组内图形排序后的各图形类型及面积
        cardSort1();
        cardSort2();
        cardSort3();
        cardSort4();
        System.out.println();
        System.out.printf("The max area:%.2f", getMax());//各组中面积之和的最大值输出
    }
}

class Card implements Comparable<Card> {
    private Shape shape;
    public Card() {}
    public Card(Shape shape) {this.shape = shape;}
    public Shape getShape() {return shape;}
    public int compareTo(Card card) {
        double area1 = shape.getArea();
        double area2 = card.getShape().getArea();
        if (area1 > area2) {//当前对象大于参数对象,返回负数
            return -1;
        } else if (area1 < area2) {//当前对象小于参数对象,返回正数
            return 1;
        } else {//两个对象相等,返回0
            return 0;}}}
//interface Comparable<E> {
//    public int compareTo(Card o);}
abstract class Shape {
    private String shapeName;//图形名字
    public Shape() {}
    public Shape(String shapeName) {this.shapeName = shapeName;}
    //图形名字的getter方法
    public String getShapeName() {return shapeName;}
    public void setShapeName(String shapeName) {this.shapeName = shapeName;}
    //计算面积的抽象方法
    public abstract double getArea();
    //判断属性值是否非法的抽象方法
    public abstract boolean validate();
    //自定义返回值
    public String toString() {
        return getShapeName() + ":" + String.format("%.2f ", getArea());}}
class Circle extends Shape {
    private double radius;//圆形半径
    public Circle() {}
    public Circle(double radius) {this.radius = radius;}
    //半径的getter方法
    public double getRadius() {return radius;}
    //求圆形的面积
    public double getArea() {return this.radius * this.radius * Math.PI;}
    //判断半径的输入值是否非法
    public boolean validate() {
        return !(this.getRadius() < 0);
    }}
class Rectangle extends Shape {
    private double width,length;//宽度,长度
    public Rectangle() {}
    public Rectangle(double width, double length) {this.width = width;this.length = length;}
    //getter方法
    public double getWidth() {return width;}
    public double getLength() {return length;}
    //求矩形的面积
    public double getArea() {return this.length * this.width;}
    //判断宽度,长度的输入值是否非法
    public boolean validate() {
        return !(this.getLength() < 0) && !(this.getWidth() < 0);
    }}
class Trapezoid extends Shape {
    private double topSide,bottomSide,height;//上底,高,下底
    public Trapezoid() {}
    public Trapezoid(double topSide, double bottomSide, double height) {this.topSide = topSide;this.bottomSide = bottomSide;this.height = height;}
    //求梯形的面积
    public double getArea() {return (this.topSide + this.bottomSide) * this.height / 2;}
    //判断上底,下底,高的输入值是否非法
    public boolean validate() {
        return !(this.height < 0) && !(this.bottomSide < 0) && !(this.topSide < 0);
    }}
class Triangle extends Shape {
    private double side1,side2,side3;//三条边
    public Triangle() {}
    public Triangle(double side1, double side2, double side3) {this.side1 = side1;this.side2 = side2;this.side3 = side3;}
    //求三角形的面积
    public double getArea() {
        double sum = (this.side1 + this.side2 + this.side3) * (this.side1 + this.side2 - this.side3) *(this.side1 + this.side3 - this.side2) * (this.side2 + this.side3 - this.side1) / 4;
        return Math.sqrt(sum) / 2;}
    //判断三边的输入值是否非法以及是否能构成三角形
    public boolean validate() {
        if (this.side1 < 0 || this.side2 < 0 || this.side3 < 0) {
            return false;
        } else return !((this.side1 + this.side2) < this.side3) && !((this.side1 + this.side3) < this.side2) && !((this.side2 + this.side3) < this.side1);
    }}

 

在此次题目集中,代码量相对较多,但整体难度不算复杂。题目集主要分为图形类、处理图形的总面积类和卡片类。

图形类包含了圆形卡片、矩形卡片、三角形卡片、梯形卡片和一个抽象图形类。每个图形类都有自己的属性和方法,通过继承和多态性的使用,实现了类的层次结构。这样的设计使得代码具有良好的可扩展性和可维护性。

处理图形的总面积类是整个程序的核心部分,它需要根据用户的输入情况将图形存入列表中,并判断输入的图形属性值是否合法。同时,它还需要输出图形的数据并计算总面积,并将图形的面积从大到小进行排序。这个类的难点在于处理用户输入和图形面积的计算和排序,但通过合理的设计和算法选择,可以较好地解决这些问题。

卡片类主要用于比较图形的面积,并自定义返回值。这个类的设计需要考虑到面向对象设计原则中的“单一职责原则”和“开-闭原则”,使得代码具有良好的可扩展性和可维护性。

同时,为了提高代码的可复用性,可以进一步完善类结构,使得系统具有更好的可扩展性和可维护性。

 

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

 

编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:

  • Java中共有53个关键字(自行百度)
  • 从键盘输入一段源码,统计这段源码中出现的关键字的数量
  • 注释中出现的关键字不用统计
  • 字符串中出现的关键字不用统计
  • 统计出的关键字及数量按照关键字升序进行排序输出
  • 未输入源码则认为输入非法

 

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //将输入的源码存入l中
        List<String> l = new ArrayList<>();
        while (in.hasNextLine()) {
            String line = in.nextLine();
            //以exit行作为结束标志
            if (line.equals("exit")) {
                break;
            }
            l.add(line);
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String str : l) {
            stringBuilder.append(str + "\n");
        }
        String result = stringBuilder.toString();
        //删除注释和字符串中的关键字,将所有的符号替换为空格,结果存入output1
        String result1 = result.replaceAll("(//.*)|(/\\*[\\s\\S]*?\\*/)", "");
        String output = result1.replaceAll("\"[^\"]*\"", "a");
        String output1 = output.replaceAll("[^+\\-*/=\\w]", " ");
        String output3 = output1.replaceAll("[+\\-*/=]", "a");

        String[] output2 = output3.split("[\\s]+");

        //53个关键字
        String[] keywordString = {"abstract", "assert", "boolean",
                "break", "byte", "case", "catch", "char", "class", "const",
                "continue", "default", "do", "double", "else", "enum",
                "extends", "for", "final", "finally", "float", "goto",
                "if", "implements", "import", "instanceof", "int",
                "interface", "long", "native", "new", "package", "private",
                "protected", "public", "return", "short", "static",
                "strictfp", "super", "switch", "synchronized", "this",
                "throw", "throws", "transient", "try", "void", "volatile",
                "while", "true", "false", "null"};
        Set<String> keywordSet = new HashSet<>(Arrays.asList(keywordString));
        //将出现的关键字存入key中
        List<String> key = new ArrayList<>();
        for (String s : keywordSet) {
            if (output.contains(s)) {
                key.add(s);
            }
        }

        //升序排序
        for (int i = 0; i < key.size(); i++) {
            Collections.sort(key, new Comparator<String>() {
                @Override
                public int compare(String s1, String s2) {
                    return s1.compareTo(s2);
                }
            });
        }

        //复制key中的关键字到数组joinedString中
        String[] joinedString = new String[key.size()];
        key.toArray(joinedString);
        Map<String, Integer> map = new TreeMap<>();

        for (int i = 0; i < joinedString.length; i++) {
            for (String out : output2) {
                if (joinedString[i].equals(out)) {
                    if (!map.containsKey(joinedString[i])) {
                        map.put(joinedString[i], 1);
                    } else {
                        int value = map.get(joinedString[i]);
                        value++;
                        map.put(joinedString[i], value);
                    }
                }
            }
        }
        if (l.size() == 0) {
            System.out.println("Wrong Format");
        } else {
            for (Map.Entry<String, Integer> entry : map.entrySet()) {
                System.out.println(entry.getValue() + "\t" + entry.getKey());
            }
        }

    }

}

 

在此次题目集中,我们需要运用HashMap和TreeMap来统计Java程序中关键词的出现次数。为了实现这个功能,我们可以按照以下步骤进行处理:

  1. 将文本存入一个字符串变量中,命名为result。
  2. 删除注释和字符串中的关键字,可以使用正则表达式来精简代码。具体来说,可以使用正则表达式来匹配并删除单行注释、多行注释和字符串中的关键字。删除后的结果存入一个新的字符串变量中,命名为output1。
  3. 将所有的符号替换为空格,可以使用正则表达式来实现。这样可以将文本中的符号与关键字分隔开来,方便后续的处理。
  4. 遍历文本,将出现的关键字存入一个集合中,可以使用HashSet来实现。这样可以去除重复的关键字,并且集合中的关键字是无序的。
  5. 将集合中的关键字按照字母顺序进行升序排序,可以使用TreeSet来实现。这样可以使得关键字按照字母顺序排列。
  6. 将排序后的关键字复制到一个数组中,命名为joinedString。
  7. 统计关键字在文本中的出现次数,可以使用HashMap来实现。将关键字作为键,出现次数作为值,存入HashMap中。
  8. 遍历HashMap,使用Map.Entry<>来输出关键字和对应的出现次数。

在代码的实现过程中,我们可以考虑使用模块化的方式来处理不同的功能,以符合面向对象设计原则中的“单一职责原则”。比如,可以将字符串的处理、单行注释的处理和多行注释的处理等功能分别封装成不同的方法或类,使得代码更加清晰、可读性更高,并且方便后续的维护和扩展。

通过掌握HashMap和TreeMap的使用,以及灵活运用正则表达式来精简代码,我们可以较好地完成题目要求,并且提高代码的可读性和可维护性。同时,我们也可以进一步思考如何优化代码的结构和设计,使得代码更加模块化和可复用。

 

三、课程成绩统计程序

 

第一次基本要求:

某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。考察的总成绩直接等于期末成绩必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。

课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

课程性质输入项:必修、选修

考核方式输入选项:考试、考察

课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

2、输出:

输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。

为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。

1)学生课程总成绩平均分按学号由低到高排序输出

格式:学号+英文空格+姓名+英文空格+总成绩平均分

如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"

2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出

格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分

如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"

3)班级所有课程总成绩平均分按班级由低到高排序输出

格式:班级号+英文空格+总成绩平均分

如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"

异常情况:

1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"

2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"

以上两种情况如果同时出现,按第一种情况输出结果。

3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"

4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"

5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

第二次迭代:

增加了实验课,实验的总成绩等于课程每次实验成绩的平均分,实验课的成绩必须为实验。

实验课程成绩信息包括:学号、姓名、课程名称、实验次数、每次成绩

实验次数至少4次,不超过9次

实验课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+实验次数+英文空格+第一次实验成绩+...+英文空格+最后一次实验成绩

实验课成绩格式:课程名称+英文空格+总成绩平均分

第三次迭代:

在第二次的基础上修改了计算总成绩的方式

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

考察的总成绩直接等于期末成绩

实验的总成绩等于课程每次实验成绩乘以权重后累加而得。

课程权重值在录入课程信息时输入。(注意:所有分项成绩的权重之和应当等于1)

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式、分项成绩数量、每个分项成绩的权重。

考试课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+平时成绩的权重+英文空格+期末成绩的权重

考察课信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

实验课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式+英文空格+分项成绩数量n+英文空格+分项成绩1的权重+英文空格+。。。+英文空格+分项成绩n的权重

实验课程成绩信息包括:学号、姓名、课程名称、每次成绩{在系列-2的基础上去掉了(实验次数),实验次数要和实验课程信息中输入的分项成绩数量保持一致}

7)如果解析考试课、实验课时,分项成绩权重值的总和不等于1,输出:课程名称+" : weight value error"

 

import java.text.Collator;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        ArrayList<Course> course = new ArrayList<>();//课程列表
        ArrayList<Selection> selection = new ArrayList<>();//选课列表
        ArrayList<AClass> clas = new ArrayList<>();//班级列表
        ArrayList<Student> student = new ArrayList<>();//学生列表
        ArrayList<CourseOut> courseOut = new ArrayList<>();//课程输出列表
        //将输入的每一行存入
        while (true) {
            String str = in.nextLine();
            String[] temp = str.split(" ");
            if (str.equals("end")) {
                break;
            }
            if (temp.length == 3) { //课程名称、课程性质、考核方式(考察)
                if (temp[0].length() <= 10 && (temp[1].equals("必修") || temp[1].equals("选修") || temp[1].equals("实验"))
                        && (temp[2].equals("考察") || temp[2].equals("考试") || temp[2].equals("实验"))) {
                    if ((temp[1].equals("必修") && temp[2].equals("考察")) || (temp[1].equals("实验") && temp[2].equals("考察"))
                            || (temp[1].equals("实验") && temp[2].equals("考试")) || (temp[1].equals("必修") && temp[2].equals("实验"))
                            || (temp[1].equals("选修") && temp[2].equals("实验"))) {
                        System.out.println(temp[0] + " : course type & access mode mismatch");//某门课程没有任何成绩信息
                    } else {
                        course.add(new Course(temp[0], temp[1], temp[2]));//加入出现的课程
                    }
                } else if (temp[0].equals("java实验") && temp[1].equals("实验")) {
                    System.out.println(temp[0] + " : course type & access mode mismatch");
                } else {
                    System.out.println("wrong format");
                }
            } else if (temp.length == 4) {//学号、姓名、课程名称、期末成绩
                try {
                    if (temp[0].length() == 8 && temp[1].length() <= 10 && temp[2].length() <= 10
                            && temp[3].matches("([1-9]?[0-9]|100)")) {
                        Course course1 = searchCourse(course, temp[2]);
                        if (course1 == null) {//课程名称不在已输入的课程列表中
                            System.out.println(temp[2] + " does not exist");
                            student.add(new Student(temp[0], temp[1]));//存入学生输出列表
                        } else {
                            if (course1.getExamWay().equals("考试")) {//输入的成绩数量和课程的考核方式不匹配
                                System.out.println(temp[0] + " " + temp[1] + " : access mode mismatch");
                                student.add(new Student(temp[0], temp[1]));
                                selection.add(new Selection(temp[0], temp[1], temp[2], -1));
                            } else {
                                selection.add(new Selection(temp[0], temp[1], temp[2], Integer.parseInt(temp[3])));
                            }
                        }
                    } else {
                        System.out.println("wrong format");
                    }
                } catch (Exception err) {
                    System.out.println("wrong format");
                }
            } else if (temp.length == 5) {//学号、姓名、课程名称、平时成绩、期末成绩     实验
                try {
                    if (temp[0].length() <= 10 && (temp[2].equals("考试"))) {
                        if (temp[1].equals("实验")) {
                            System.out.println(temp[0] + " : course type & access mode mismatch");
                        } else {
                            if ((float) (Double.parseDouble(temp[3]) + Double.parseDouble(temp[4])) != 1)
                                System.out.println(temp[0] + " : weight value error");
                            else {
                                if (searchCourse(course, temp[0]) == null) {
                                    course.add(new Course(temp[0], temp[1], temp[2]));
                                    Course course1 = searchCourse(course, temp[0]);
                                    course1.weight[0] = Double.parseDouble(temp[3]);
                                    course1.weight[1] = Double.parseDouble(temp[4]);
                                }
                            }
                        }
                    }
                    if (temp[0].length() <= 10 && temp[1].equals("实验")) {
                        System.out.println("wrong format");
                    }
                    if (temp[0].length() == 8 && temp[1].length() <= 10 && temp[2].length() <= 10
                            && temp[3].matches("([1-9]?[0-9]|100)") && temp[4].matches("([1-9]?[0-9]|100)")) {
                        Course course1 = searchCourse(course, temp[2]);
                        if (course1 == null) {//课程名称不在已输入的课程列表中
                            System.out.println(temp[0] + " does not exist");
                        } else {
                            if (course1.getProperty().equals("实验")) {//输入的成绩数量和课程的考核方式不匹配
                                System.out.println("wrong format");
                            } else {
                                selection.add(new Selection(temp[0], temp[1], temp[2], Integer.parseInt(temp[3]),
                                        Integer.parseInt(temp[4])));
                            }
                        }
                    } else {
                        System.out.println("wrong format");
                    }
                } catch (Exception err) {
                    System.out.println("wrong format");
                }
            } else {//实验
                if (temp[0].length() <= 10 && (temp[1].equals("必修") || temp[1].equals("选修")) && temp[2].equals("实验")) {
                    System.out.println(temp[0] + " : course type & access mode mismatch");
                }
                if (temp[0].length() <= 10 && temp[1].equals("实验") && temp[2].equals("实验")) {
                    int length1 = temp.length;
                    length1 = length1 - 4;
                    if (length1 != Integer.parseInt(temp[3])) {
                        System.out.println("java : number of scores does not match");
                    } else {
                        if (Integer.parseInt(temp[3]) < 4 || Integer.parseInt(temp[3]) > 9) {
                            System.out.println("wrong format");
                            course.add(new Course(temp[0], temp[1], temp[2]));
                            break;
                        }
                        double sum = 0;
                        for (int i = 0; i < length1; i++) {
                            sum += Double.parseDouble(temp[4 + i]);//每次实验权重相加
                        }
                        if ((float) sum != 1) {
                            System.out.println("java : weight value error");
                        } else {
                            if (searchCourse(course, temp[0]) == null) {
                                course.add(new Course(temp[0], temp[1], temp[2]));
                                Course course1 = searchCourse(course, temp[0]);
                                for (int i = 0; i < length1; i++) {
                                    course1.weight[i] = Double.parseDouble(temp[4 + i]);
                                }
                            }
                        }
                    }
                } else {
                    int length = temp.length;
                    length = length - 3;
                    if (temp[0].length() == 8 && temp[1].length() <= 10 && length <= 9 && length >= 4) {
                        Course course1 = searchCourse(course, temp[2]);
                        if (course1 == null) {
                            System.out.println(temp[2] + " does not exist");
                        } else {
                            if (length != course1.weight.length - 5) {
                                System.out.println(temp[0] + " " + temp[1] + " : access mode mismatch");
                                student.add(new Student(temp[0], temp[1]));
                                selection.add(new Selection(temp[0], temp[1], temp[0].substring(0, 6), -1));
                            } else {
                                double sum1 = 0;
                                for (int i = 0; i < length; i++) {
                                    if (Integer.parseInt(temp[3 + i]) < 0 || Integer.parseInt(temp[3 + i]) > 100) {
                                        System.out.println("wrong format");
                                        sum1 = -1;
                                        break;
                                    } else
                                        sum1 += Integer.parseInt(temp[3 + i]) * course1.weight[i];
                                }
                                if (sum1 != -1) {
                                    selection.add(new Selection(temp[0], temp[1], temp[2], (int) sum1));
                                }
                            }
                        }
                    }
                }
                if (temp.length < 3 || temp.length > 13)
                    System.out.println("wrong format");
            }
        }
        //创建班级,如果存在则将记录传入班级
        for (Selection selection1 : selection) {
            AClass clas1 = searchAClass(clas, (selection1.getstudent().getID()).substring(0, 6));
            if (clas1 == null) {
                clas.add(new AClass((selection1.getstudent().getID()).substring(0, 6), selection1));
            } else {
                clas1.setSelection(selection1);
            }
        }

        //遍历所有班级
        for (AClass clas2 : clas) {
            int i = 0, sum = 0;
            for (Selection selection2 : clas2.getSelection()) {//查找selection
                selection2.setTotalScore();//得到每条记录里面的总分数
                sum += selection2.getTotalScore();
                i++;
            }
            int classAverage = (sum / i);
            clas2.setClassAver(classAverage);
        }

        selection.sort(Comparator.comparingInt(a -> a.getstudent().getIDNumber()));

        //student类创建,如果有则传入信息
        for (Selection selection2 : selection) {
            Student student2 = searchStudent(student, selection2.getstudent().getID());
            if (student2 == null) {
                student.add(new Student(selection2.getstudent().getID(), selection2.getstudent().getName()));
            }
            int sum = 0, i = 0;
            Student student3 = searchStudent(student, selection2.getstudent().getID());
            for (Selection selection3 : selection) {
                selection3.setTotalScore();
                if (selection3.getstudent().getName().equals(student3.getName()) && selection3.getstudent().getID().equals(student3.getID())) {
                    sum += selection3.getTotalScore();//匹配学号姓名,计算学生总分
                    i++;
                }
            }
            int aver = (sum / i);
            student3.setAverageScore(aver);
        }

        for (Student student4 : student) {
            if (student4.getAverageScore() < 0) {//判断这个学生是否有成绩
                System.out.println(student4.getIDNumber() + " " + student4.getName() + " did not take any exams");
            } else
                System.out.println(student4.getIDNumber() + " " + student4.getName() + " " + student4.getAverageScore());
        }

        for (Course course4 : course) {//计算单门课程的平均分
            Selection selection7 = searchselection(selection, course4.getName());
            if (selection7 != null) {
                int sumDaily = 0, sumExam = 0, sumAssess = 0, sum = 0, i = 0;
                for (Selection selection4 : selection) {
                    if (course4.getName().equals(selection4.getcourse().getName())) {
                        sumDaily += selection4.getdailyscore().getScore();
                        sumExam += selection4.getExamScores().getScore();
                        sumAssess += selection4.getassscore().getScore();
                        sum += selection4.getTotalScore();
                        i++;
                    }
                }
                //平时成绩,考试成绩,考察成绩,总分成绩的平均分
                int averDaily = (sumDaily / i), averExam = (sumExam / i), averAssess = (sumAssess / i), aver = (sum / i);
                CourseOut courseOut1 = searchCourseout(courseOut, course4.getName());
                if (courseOut1 == null)
                    courseOut.add(new CourseOut(course4.getName(), averDaily, averExam, averAssess, aver));
            }
        }

        for (Course course3 : course) {
            Selection selection7 = searchselection(selection, course3.getName());
            if (selection7 == null) {//没有输入成绩
                System.out.println(course3.getName() + " has no grades yet");
            } else {
                Comparator<Object> comparator = Collator.getInstance(Locale.CHINA);
                courseOut.sort((p1, p2) -> comparator.compare(p1.getName(), p2.getName()));
            }
        }

        for (CourseOut courseOut1 : courseOut) {//平时成绩平均分、考试成绩平均分、总成绩平均分
            Course course1 = searchCourse(course, courseOut1.getName());
            if (course1 != null && course1.getExamWay().equals("实验")) {
                System.out.println(courseOut1.getName() + " " + courseOut1.getaAver());
                continue;
            }
            if (courseOut1.getaAver() < 0)
                System.out.println(courseOut1.getName() + " " + courseOut1.getDailyAver() + " " + courseOut1.getExamAver() + " " + courseOut1.getAverageScore());
            else
                System.out.println(courseOut1.getName() + " " + courseOut1.getaAver() + " " + courseOut1.getAverageScore());
        }
        clas.sort(Comparator.comparingInt(AClass::getClassNumber));

        //班级没有任何成绩信息
        for (AClass clas3 : clas) {
            if (clas3.getClassAver() < 0)
                System.out.println(clas3.getClassNum() + " has no grades yet");
            else
                System.out.println(clas3.getClassNum() + " " + clas3.getClassAver());
        }
    }

    public static Course searchCourse(ArrayList<Course> course, String name) {
        for (Course course1 : course) {
            if (course1 == null)
                return null;
            if (name.equals(course1.getName()))
                return course1;
        }
        return null;
    }

    public static AClass searchAClass(ArrayList<AClass> clas, String classNum) {
        for (AClass clas1 : clas) {
            if (clas1 == null)
                return null;
            if (classNum.equals(clas1.getClassNum()))
                return clas1;
        }
        return null;
    }

    public static CourseOut searchCourseout(ArrayList<CourseOut> courseOut, String name) {
        for (CourseOut courseOut1 : courseOut) {
            if (courseOut1 == null)
                return null;
            if (name.equals(courseOut1.getName()))
                return courseOut1;
        }
        return null;
    }

    public static Selection searchselection(ArrayList<Selection> selection, String name) {
        for (Selection selection5 : selection) {
            if (selection5 == null)
                return null;
            if (name.equals(selection5.getcourse().getName()))
                return selection5;
        }
        return null;
    }

    public static Student searchStudent(ArrayList<Student> student, String ID) {
        for (Student student1 : student) {
            if (student1 == null)
                return null;
            if (ID.equals(student1.getID()))
                return student1;
        }
        return null;
    }
}

class Student {
    private final String ID;
    private final String name;
    private int averageScore = -1;

    public Student(String ID, String name) {
        this.ID = ID;
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public String getID() {
        return this.ID;
    }

    public int getIDNumber() {
        return Integer.parseInt(this.ID);
    }

    public int getAverageScore() {
        return this.averageScore;
    }

    public void setAverageScore(int averageScore) {
        this.averageScore = averageScore;
    }
}

class CourseOut {
    private final String name;
    private final int dailyAver;
    private final int examAver;
    private final int assessAver;
    private final int averageScore;

    public CourseOut(String name, int dailyAver, int examAver, int assessAver, int averageScore) {
        this.name = name;
        this.dailyAver = dailyAver;
        this.examAver = examAver;
        this.assessAver = assessAver;
        this.averageScore = averageScore;
    }

    public String getName() {
        return this.name;
    }

    public int getDailyAver() {
        return dailyAver;
    }

    public int getExamAver() {
        return examAver;
    }

    public int getaAver() {
        return this.assessAver;
    }

    public int getAverageScore() {
        return this.averageScore;
    }
}

class Course {
    private final String name;
    private String property;
    private String examWay;
    double[] weight = new double[9];

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

    public Course(String name, String property, String examWay) {
        this.name = name;
        this.property = property;
        this.examWay = examWay;
    }

    public String getName() {
        return this.name;
    }

    public String getExamWay() {
        return this.examWay;
    }

    public String getProperty() {
        return this.property;
    }

}

class Selection {
    Course course;
    Student student;
    ExamScores examScores = new ExamScores();
    DailyScore dailyScore = new DailyScore();
    AssScore assScore = new AssScore();

    private int totalScore;

    public Selection(String ID, String name, String courseName, int dailyScores, int examScore) {
        student = new Student(ID, name);
        course = new Course(courseName);
        dailyScore = new DailyScore(dailyScores);
        examScores = new ExamScores(examScore);
    }

    public Selection(String ID, String name, String courseName, int assessScore) {
        student = new Student(ID, name);
        course = new Course(courseName);
        assScore = new AssScore(assessScore);
    }

    public Student getstudent() {
        return this.student;
    }

    public Course getcourse() {
        return this.course;
    }

    public DailyScore getdailyscore() {
        return this.dailyScore;
    }

    public ExamScores getExamScores() {
        return this.examScores;
    }

    public AssScore getassscore() {
        return this.assScore;
    }

    public void setTotalScore() {
        if (this.assScore.getScore() == -1) {
            this.totalScore = (int) (this.examScores.getScore() * 0.7 + this.dailyScore.getScore() * 0.3);
        } else
            this.totalScore = this.assScore.getScore();
    }

    public int getTotalScore() {
        return this.totalScore;
    }
}

class AClass {
    private final String classNum;//班级号
    ArrayList<Selection> studentSelection = new ArrayList<>();
    private int classAver = -1;

    public AClass(String classNum, Selection selection) {
        this.classNum = classNum;
        if (selection.getassscore().getScore() == -1)
            studentSelection.add(new Selection(selection.getstudent().getID(), selection.getstudent().getName(),
                    selection.getcourse().getName(), selection.getdailyscore().getScore(), selection.getExamScores().getScore()));
        else
            studentSelection.add(new Selection(selection.getstudent().getID(), selection.getstudent().getName(),
                    selection.getcourse().getName(), selection.getassscore().getScore()));
    }

    public void setSelection(Selection selection) {
        if (selection.getassscore().getScore() == -1)
            studentSelection.add(new Selection(selection.getstudent().getID(), selection.getstudent().getName(),
                    selection.getcourse().getName(), selection.getdailyscore().getScore(), selection.getExamScores().getScore()));
        else
            studentSelection.add(new Selection(selection.getstudent().getID(), selection.getstudent().getName(),
                    selection.getcourse().getName(), selection.getassscore().getScore()));
    }

    public ArrayList<Selection> getSelection() {
        return this.studentSelection;
    }

    public String getClassNum() {
        return this.classNum;
    }

    public int getClassNumber() {
        return Integer.parseInt(this.classNum);
    }

    public void setClassAver(int classAver) {
        this.classAver = classAver;
    }

    public int getClassAver() {
        return this.classAver;
    }
}


class DailyScore {
    protected int score = -1;

    public DailyScore() {
    }

    public DailyScore(int score) {
        this.score = score;
    }

    public int getScore() {
        return this.score;
    }
}

class ExamScores {
    protected int score = -1;

    public ExamScores() {
    }

    public ExamScores(int score) {
        this.score = score;
    }

    public int getScore() {
        return this.score;
    }
}

class AssScore {
    protected int score = -1;

    public AssScore() {
    }

    public AssScore(int score) {
        this.score = score;
    }

    public int getScore() {
        return this.score;
    }
}

 

在此次题目集中,我们需要运用ArrayList来存储课程、学生、选择和班级的信息,并完成相应的操作,比如计算平均分等。为了实现这个功能,我们可以按照以下步骤进行处理:

  1. 创建五个ArrayList,分别用于存储课程、学生、选择和班级,班级输出的信息。可以使用ArrayList的泛型来指定存储的数据类型,比如使用ArrayList<String>来存储字符串类型的数据。
  2. 遍历输入的字符串,通过判断字符串的长度来分类处理。
  3. 对于课程信息,可以进一步区分每个字符串的内容,比如判断是否为必修课程、实验课程等。根据题目要求,可以使用正则表达式来判断分数。
  4. 对于学生信息、选择信息和班级信息,可以判断是否为错误输入。比如,可以检查学生信息中是否存在重复的学生ID,选择信息中是否存在重复的学生ID和课程ID,班级信息中是否存在重复的班级ID等。如果存在错误输入,可以进行相应的处理,比如输出错误信息。
  5. 遍历每个ArrayList,进行相应的操作。比如,可以计算每个学生的平均分。
  6. 根据题目要求,可以进一步优化代码的结构和设计。比如,可以将不同的功能划分为不同的方法或类,以符合面向对象设计原则中的“单一职责原则”。这样可以使得代码更加清晰、可读性更高,并且方便后续的维护和扩展。

通过运用ArrayList来存储信息,并进行相应的操作,我们可以较好地完成题目要求,并且提高代码的可读性和可维护性。同时,我们也可以进一步思考如何优化代码的结构和设计,使得代码更加模块化和可复用。

 
 

踩坑心得:

1、在开始编写代码之前,先仔细阅读问题描述,确保完全理解需求。然后,可以进行一些思考和规划,考虑如何解决问题、选择合适的数据结构和算法等。这样可以避免在编写代码时出现频繁的修改和重构。

2、在编写代码时,可以采用渐进式开发的方式。先编写一小部分代码,然后进行测试和调试。确保这部分代码可以正常工作后,再逐步添加和调试其他部分。这样可以快速定位和解决问题,并减少调试的难度。

3、理解错误信息和异常:在编写代码时,可能会遇到各种错误信息和异常。不要害怕这些错误信息,而是要学会理解它们的含义。错误信息通常会指示出问题的位置和原因,可以根据错误信息进行定位和修复。同时,也要学会使用调试器和日志等工具,辅助定位和解决问题。

4、在编写代码时,尽量避免重复编写已经存在的功能。学会利用现有的库、框架和工具,它们可以帮助你节省时间和精力。在使用这些工具时,要注意它们的文档和示例,了解它们的使用方法和最佳实践。

5、简化和优化代码:编写代码时,要尽量保持代码的简洁性和可维护性。避免冗余和复杂的代码,采用简单而直观的解决方案。这样可以使代码更易于理解和调试,并减少潜在的错误。同时,要学会优化代码,提高其性能和效率。这包括避免不必要的循环、减少内存和资源的使用等。

 

总结:

以下为这个学习JAVA学习以来的总结:

1、简洁性:使用有意义的命名,避免使用模棱两可或过于简单的命名。命名应准确地描述变量或函数的用途和功能。避免冗余的代码,删除不必要的注释、空格和空行。代码应该尽可能简洁、清晰和易于理解。

2、规范化和可读性:遵循编码规范和最佳实践,如使用一致的缩进、命名约定和代码风格。这有助于提高代码的可读性和可维护性。要记得使用注释来解释代码的目的、实现细节和注意事项。注释应该简洁明了,这样可以提高代码的可读性。

3、可维护性:使用模块化的设计,将代码分解为小的、可重用的部分。这样可以简化代码的维护和修改。遵循设计原则和模式,如单一职责原则、开闭原则和依赖倒置原则等。这些原则有助于构建可扩展和可维护的代码。

总的来说,编写高质量的代码需要不断学习和实践。简洁性、规范化、可读性、可维护性、错误处理、性能优化、测试和调试是关键要点。