pta第三次大作业总结

OK,最后一次大作业总结,话不多说直接展示

一、前言

这几次的大作业只能说很有难度了,题目量不算大,但是难是真的难。

二、设计与分析

(1)课程成绩统计程序-2

课程成绩统计程序-2在第一次的基础上增加了实验课,以下加粗字体显示为本次新增的内容。

某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。

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

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

实验的总成绩等于课程每次实验成绩的平均分

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。

1、输入:

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

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

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

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

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

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

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

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

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

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

以上信息的相关约束:

1)平时成绩和期末成绩的权重默认为0.3、0.7

2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

3)学号由8位数字组成

4)姓名不超过10个字符

5)课程名称不超过10个字符

6)不特别输入班级信息,班级号是学号的前6位。

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)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

参考类图(与第一次相同,其余内容自行补充):


e724fa4193aa9ee32e78a68cd96fd6df_22401e04-c501-4b28-bb65-dabe39d374e7.png

 

输入样例1:

在这里给出一组输入。例如:

java 实验 实验
20201103 张三 java 4 70 80 90
end

输出样例1:

在这里给出相应的输出。例如:

20201103 张三 : access mode mismatch
20201103 张三 did not take any exams
java has no grades yet
202011 has no grades yet

输入样例2:

在这里给出一组输入。例如:

java 实验 实验
20201103 张三 java 3 70 80 90
end

输出样例2:

在这里给出相应的输出。例如:

wrong format
java has no grades yet

输入样例3:

在这里给出一组输入。例如:

java 必修 实验
20201103 张三 java 3 70 80 90 100
end

输出样例3:

在这里给出相应的输出。例如:

java : course type & access mode mismatch
wrong format

输入样例4:

在这里给出一组输入。例如:

java 必修 实验
20201103 张三 java 4 70 80 90 105
end

输出样例4:

在这里给出相应的输出。例如:

java : course type & access mode mismatch
wrong format

 

输入样例5:

在这里给出一组输入。例如:

java 选修 考察
C语言 选修 考察
java实验 实验 实验
编译原理 必修 考试
20201101 王五 C语言 76
20201216 李四 C语言 78
20201307 张少军 编译原理 82 84
20201103 张三 java实验 4 70 80 90 100
20201118 郑觉先 java 80
20201328 刘和宇 java 77
20201220 朱重九 java实验 4 60 60 80 80
20201132 王萍 C语言 40
20201302 李梦涵 C语言 68
20201325 崔瑾 编译原理 80 84
20201213 黄红 java 82
20201209 赵仙芝 java 76
end

输出样例5:

在这里给出相应的输出。例如:

20201101 王五 76
20201103 张三 85
20201118 郑觉先 80
20201132 王萍 40
20201209 赵仙芝 76
20201213 黄红 82
20201216 李四 78
20201220 朱重九 70
20201302 李梦涵 68
20201307 张少军 83
20201325 崔瑾 82
20201328 刘和宇 77
C语言 65 65
java 78 78
java实验 77
编译原理 81 84 82
202011 70
202012 76
202013 77
先给出代码:

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


public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String s_record = s.nextLine();
ParseInput handle=new ParseInput();
while (!s_record.equals("end")) {
handle.parseInput(s_record);
s_record = s.nextLine();
}

handle.MySort();
handle.studentScore();
handle.CourseScore();
handle.ClassScore();
}
}

class ParseInput{
private final ArrayList<SelectCourse> selectCourses = new ArrayList<>();
private final ArrayList<Course> courses = new ArrayList<>();
private final ArrayList<Student> students = new ArrayList<>();
private final ArrayList<String> Class = new ArrayList<>();
private final HashMap<String,String> courseMethod=new HashMap();
public void parseInput(String input){
String []inputs=input.split(" ");
if(InputMatching.matchingInput(input)==1){
courseMethod.put(inputs[0],inputs[2]);
if(checkCourse(inputs[0])!=null)return;
else {
if(inputs[1].equals("必修")&&(!inputs[2].equals("考试"))){
System.out.println(inputs[0]+" : course type & access mode mismatch");
}
else if(inputs[1].equals("选修")&&!(inputs[2].equals("考试")||inputs[2].equals("考察"))){
System.out.println(inputs[0]+" : course type & access mode mismatch");
}
else if(inputs[1].equals("实验")&&!(inputs[2].equals("实验"))){
System.out.println(inputs[0]+" : course type & access mode mismatch");
}
else courses.add(new Course(inputs[0],inputs[1],inputs[2]));
}
}
else if(InputMatching.matchingInput(input)==2){
Course findcourse=checkCourse(inputs[2]);
if(inputs.length>5&&(Integer.parseInt(inputs[3])<4||Integer.parseInt(inputs[3])>9)) {
System.out.println("wrong format");
return;
}
Student newStudent = new Student(inputs[0],inputs[1]);
if(!checkStudent(newStudent.getNum()))students.add(newStudent);
if(!checkClass(inputs[0].substring(0,6))){
Class.add(inputs[0].substring(0,6));
}
if(checkSelect(inputs[0],inputs[2]))return;
if(findcourse==null){

System.out.println(inputs[2]+" does not exist");
return;
}
else if(findcourse.getMethod().equals("考试")&&inputs.length!=5){
System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
}
else if(findcourse.getMethod().equals("考察")&&inputs.length!=4){
System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
}
else if(findcourse.getMethod().equals("实验")&&(inputs.length-4!=Integer.parseInt(inputs[3]))){
System.out.println(inputs[0]+' '+inputs[1]+" : access mode mismatch");
}
else{
SelectCourse newSelectCourse=new SelectCourse();
newSelectCourse.setCourse(findcourse);
Grade grade=null;
if(findcourse.getMethod().equals("考试")){
ExamGrade examGrade=new ExamGrade();
examGrade.setUsualGrade(Integer.parseInt(inputs[3]));
examGrade.setFinalGrade(Integer.parseInt(inputs[4]));
grade=examGrade;
}
else if(findcourse.getMethod().equals("实验")){
NoExamGrade noExamGrade=new NoExamGrade();
double sumScore=0;
for (int i=4;i<inputs.length;i++)sumScore+=Integer.parseInt(inputs[i]);
noExamGrade.setFinalGrade((int)(sumScore/Integer.parseInt(inputs[3])));
grade=noExamGrade;
}
else {
NoExamGrade noExamGrade=new NoExamGrade();
noExamGrade.setFinalGrade(Integer.parseInt(inputs[3]));
grade=noExamGrade;
}
newSelectCourse.setGrade(grade);
newSelectCourse.setStudent(newStudent);
selectCourses.add(newSelectCourse);
}
}
else System.out.println("wrong format");
}
private Course checkCourse(String courseName){
for (Course course:courses){
if(course.getName().equals(courseName))return course;
}
return null;
}
private Boolean checkStudent(String num){
for (Student student:students){
if(student.getNum().equals(num))return true;
}
return false;
}
private Boolean checkClass(String classnum){
for (String cname:Class){
if(cname.equals(classnum))return true;
}
return false;
}

private Boolean checkSelect(String stunum,String cname){
for (SelectCourse selectCourse:selectCourses){
if(selectCourse.getStudent().getNum().equals(stunum)&&selectCourse.getCourse().getName().equals(cname))return true;
}
return false;
}

public void studentScore(){

for (Student student:students){
double sum=0;
int count=0;
for (SelectCourse selectCourse:selectCourses){
if (selectCourse.getStudent().getNum().equals(student.getNum()))
{
sum+=selectCourse.getGrade().getTotalGrade();
count++;
}
}
if(count==0) System.out.println(student.getNum()+' '+student.getName()+' '+"did not take any exams");
else System.out.println(student.getNum()+' '+student.getName()+' '+(int)(sum/count));
}
}
public void CourseScore(){
for (Course course:courses){
double sumUsualScore=0;
double sumFinalScore=0;
double sumTotalScore=0;
int count=0;
for(SelectCourse selectCourse:selectCourses){
if(selectCourse.getCourse().getName().equals(course.getName())){
count++;
sumTotalScore+=selectCourse.getGrade().getTotalGrade();
sumFinalScore+=selectCourse.getGrade().getFinalGrade();
if(selectCourse.getCourse().getMethod().equals("考试")){
sumUsualScore+=selectCourse.getGrade().getUsualGrade();
}
}
}
if (count==0) System.out.println(course.getName()+' '+"has no grades yet");
else if(course.getMethod().equals("考试"))System.out.println(course.getName()+' '+(int)(sumUsualScore/count)+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
else if(course.getMethod().equals("考察"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count)+' '+(int)(sumTotalScore/count));
else if(course.getMethod().equals("实验"))System.out.println(course.getName()+' '+(int)(sumFinalScore/count));
}
}
public void ClassScore(){
for (String classnum:Class){
double sum=0;
int count=0;
for (SelectCourse selectCourse:selectCourses){
if(selectCourse.getStudent().getNum().substring(0,6).equals(classnum)){
sum+=selectCourse.getGrade().getTotalGrade();
count++;
}
}
if(count==0) System.out.println(classnum+' '+"has no grades yet");
else System.out.println(classnum+' '+(int)(sum/count));
}
}
public void MySort(){
students.sort(Comparator.comparing(Student::getNum));
courses.sort((x,y)->{
Collator instance = Collator.getInstance(Locale.CHINA);
return instance.compare(x.getName(), y.getName());
} );
Collections.sort(Class);
}
}


abstract class Grade{
double TotalGrade;

public int getTotalGrade() {
return (int) TotalGrade;
}

public int getUsualGrade() {
return 0;
}

public int getFinalGrade() {
return 0;
}

}

class ExamGrade extends Grade{
int UsualGrade;
int FinalGrade;
public int getTotalGrade(){
return (int)(0.3*this.getUsualGrade()+0.7*this.getFinalGrade());
}

public int getUsualGrade() {
return UsualGrade;
}

public void setUsualGrade(int usualGrade) {
UsualGrade = usualGrade;
}

public int getFinalGrade() {
return FinalGrade;
}

public void setFinalGrade(int finalGrade) {
FinalGrade = finalGrade;
}
}
class NoExamGrade extends Grade{
int FinalGrade;
public int getTotalGrade(){
return FinalGrade;
}

public int getFinalGrade() {
return FinalGrade;
}

public void setFinalGrade(int finalGrade) {
FinalGrade = finalGrade;
}
}
class Course{
String name;
String kind;
String method;

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

public String getName() {
return name;
}

public String getMethod() {
return method;
}

}

class Student{
String num;
String name;

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

public String getNum() {
return num;
}

public String getName() {
return name;
}

}

class SelectCourse{
Course course;
Student student;
Grade grade;

public Course getCourse() {
return course;
}

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

public Student getStudent() {
return student;
}

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

public Grade getGrade() {
return grade;
}

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


class InputMatching {
static String stuNumMatching = "[0-9]{8}";
static String stuNameMatching = "\\S{1,10}";
static String scoreMatching = "(\\d|[1-9]\\d|100)";
static String courseNameMatching = "\\S{1,10}";
static String courseTypeMatching = "(选修|必修|实验)";
static String checkcourseTypeMatching = "(考试|考察|实验)";
static String courseInput = courseNameMatching + " " + courseTypeMatching + " " + checkcourseTypeMatching;
static String scoreInput = stuNumMatching + " " + stuNameMatching + " " + courseNameMatching + " " +
scoreMatching + "(\\s"+scoreMatching+")*";
public static int matchingInput(String s) {
if (matchingCourse(s)) {
return 1;
}
if (matchingScore(s)) {
return 2;
}
return 0;
}

private static boolean matchingCourse(String s) {
return s.matches(courseInput);
}

private static boolean matchingScore(String s) {

return s.matches(scoreInput);
}

}

PowerDesigner分析:

 SourceMonitor分析:

 总结:

这段代码实现了一个简单的学生成绩管理系统,通过输入学生和课程的信息,可以进行成绩统计和排序。

  1. 主程序入口:程序从标准输入中读取用户输入的信息,直到输入"end"为止。然后调用ParseInput类的方法进行解析和处理。

  2. ParseInput类:负责解析用户输入的信息,并对输入的数据进行验证和处理。主要包括以下方法:

    • parseInput:解析用户输入的信息,根据输入的格式判断是课程信息还是学生选课信息,并进行相应的处理。

    • checkCoursecheckStudentcheckClasscheckSelect:检查课程、学生、班级、选课是否已存在。

    • studentScoreCourseScoreClassScore:对学生成绩进行统计和输出。

    • MySort:对学生、课程和班级进行排序。

  3. Grade抽象类:定义了成绩的抽象概念和方法。

  4. ExamGradeNoExamGrade类:继承自Grade类,分别表示有考试成绩和无考试成绩,并实现了相应的方法。

  5. Course类:表示课程的信息,包括名称、类型和考试方式。

  6. Student类:表示学生的基本信息,包括学号和姓名。

  7. SelectCourse类:表示学生选课的信息,包括课程、学生和成绩。

  8. InputMatching类:用于对输入的数据进行格式匹配,确保输入数据符合要求。

总体而言,这段代码实现了一个简单的学生成绩管理系统,通过面向对象的方式对学生、课程和选课等信息进行抽象和处理,实现了成绩统计和排序的功能。代码结构清晰,逻辑简洁,但可能还有一些可以改进的地方,比如加入异常处理、优化算法等。

(2)立体图形问题

编程求得正方体和正三棱锥的表面积和体积,要求必须体现扩展性(继承)和多态性。

类结构如下图所示(参考):

image.png
试编程完成如上类设计,主方法源码如下(可直接拷贝使用):

 
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);
    double side = input.nextDouble();
        
    display(new Cube(side));
    display(new RegularPyramid(side));
}

其中,display(Solid solid)方法为定义在Main类中的静态方法,作用为体现程序的多态性。

注:正三棱锥的体积计算公式为底面积*高/3。

输入格式:

输入一个实型数,分别作为正方体的边长和正三棱锥的边长。

输出格式:

分别输出正方体的表面积、体积以及正棱锥的表面积和体积。保留两位小数,建议使用String.format(“%.2f”,value)

进行小数位数控制。

 

输入样例:

在这里给出一组输入。例如:

2.5

输出样例:

在这里给出相应的输出。例如:

37.50
15.63
10.83
1.84
先给出代码:

import java.util.Scanner;

abstract class Solid {
protected double side;

public Solid(double side) {
this.side = side;
}

public abstract double getSurfaceArea();

public abstract double getVolume();
}

class Cube extends Solid {
public Cube(double side) {
super(side);
}

public double getSurfaceArea() {
return 6 * Math.pow(side, 2);
}

public double getVolume() {
return Math.pow(side, 3);
}
}

class RegularPyramid extends Solid {
public RegularPyramid(double side) {
super(side);
}

public double getSurfaceArea() {
double baseArea = (Math.sqrt(3) / 4) * Math.pow(side, 2);
double slantHeight = Math.sqrt(Math.pow(side, 2) - Math.pow(side / 2, 2));
double lateralArea = 3 * (side * slantHeight) / 2;
return baseArea + lateralArea;
}

public double getVolume() {
return (Math.pow(side, 3) * Math.sqrt(2)) / 12;
}
}

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double side = input.nextDouble();

display(new Cube(side));
display(new RegularPyramid(side));
}

public static void display(Solid solid) {
System.out.println(String.format("%.2f", solid.getSurfaceArea()));
System.out.println(String.format("%.2f", solid.getVolume()));
}
}

PowerDesigner分析:

 SourceMonitor分析:

 总结:这道题目·是期末考试的题目,难度不大,照着类图一个一个写就好了,主要问题出在公式上,不知道正三棱锥体积公式是啥

(3)魔方问题:

问题描述:本问题中的魔方有两种,一种是正方体魔方,一种是正三棱锥魔方,其中,正方体或正三棱锥魔方是由单元正方体或正三棱锥组成,单元正方体或正三棱锥的个数由阶数(即层数)决定,即魔方边长=阶数*单元边长。魔方如下图所示:

image.png

 

利用“立体图形”问题源码,实现如下功能:

魔方有三个属性:颜色,阶数,类型(正方体魔方、正三棱锥魔方),程序要求输出魔方的颜色、表面积和体积。参考设计类图如下所示:

image.png

主方法部分可参考如下源码(可拷贝直接使用):

 

 
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color = input.next();
        int layer = input.nextInt();
        double side = input.nextDouble();        
        
        RubikCube cube1 = new SquareCube(color, layer,new Cube(side)); 
                
        color = input.next();
        layer = input.nextInt();
        side = input.nextDouble();
        
        RubikCube cube2 = new RegularPyramidCube(color, layer,new RegularPyramid(side));
        display(cube1);
        display(cube2);
    }
}

其中,display(RubikCube cube)方法为Main类中定义的静态方法,用户输出魔方的信息,用于体现多态性。

输入格式:

第一部分:正方体魔方颜色、阶数、单元正方体边长,以空格或回车分隔;

第二部分:正三棱锥魔方颜色、阶数、单元正三棱锥边长,以空格或回车分隔。

输出格式:

正方体魔方颜色

正方体魔方表面积

正方体魔方体积

正三棱锥魔方颜色

正三棱锥魔方表面积
正三棱锥魔方体积

注:小数点保留两位

输入样例:

在这里给出一组输入。例如:

red 3 4.5
black 4 2.1

输出样例:

在这里给出相应的输出。例如:

red
1093.50
2460.38
black
122.21
69.85
先给出代码:

import java.util.Scanner;

abstract class Solid {
protected double side;

public Solid(double side) {
this.side = side;
}

public abstract double getSurfaceArea();

public abstract double getVolume();
}

class Cube extends Solid {
public Cube(double side) {
super(side);
}

public double getSurfaceArea() {
return 6 * Math.pow(side, 2);
}

public double getVolume() {
return Math.pow(side, 3);
}
}

class RegularPyramid extends Solid {
public RegularPyramid(double side) {
super(side);
}

public double getSurfaceArea() {
double baseArea = (Math.sqrt(3) / 4) * Math.pow(side, 2);
double slantHeight = Math.sqrt(Math.pow(side, 2) - Math.pow(side / 2, 2));
double lateralArea = 3 * (side * slantHeight) / 2;
return baseArea + lateralArea;
}

public double getVolume() {
return (Math.pow(side, 3) * Math.sqrt(2)) / 12;
}
}

abstract class RubikCube {
protected String color;
protected int layer;
protected Solid solid;

public RubikCube(String color, int layer, Solid solid) {
this.color = color;
this.layer = layer;
this.solid = solid;
}

public abstract double getTotalSurfaceArea();

public abstract double getTotalVolume();

public String getColor() {
return color;
}
}

class SquareCube extends RubikCube {
public SquareCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

public double getTotalSurfaceArea() {
return solid.getSurfaceArea() * Math.pow(layer, 2);
}

public double getTotalVolume() {
return solid.getVolume() * Math.pow(layer, 3);
}
}

class RegularPyramidCube extends RubikCube {
public RegularPyramidCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

public double getTotalSurfaceArea() {
return solid.getSurfaceArea() * Math.pow(layer, 2);
}

public double getTotalVolume() {
return solid.getVolume() * Math.pow(layer, 3);
}
}

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);

String color = input.next();
int layer = input.nextInt();
double side = input.nextDouble();

RubikCube cube1 = new SquareCube(color, layer, new Cube(side));

color = input.next();
layer = input.nextInt();
side = input.nextDouble();

RubikCube cube2 = new RegularPyramidCube(color, layer, new RegularPyramid(side));
display(cube1);
display(cube2);
}

public static void display(RubikCube cube) {
System.out.println(cube.getColor());
System.out.println(String.format("%.2f", cube.getTotalSurfaceArea()));
System.out.println(String.format("%.2f", cube.getTotalVolume()));
}
}

PowerDesigner分析:

 SourceMonitor分析:

 总结:

该代码实现了一个立方体和正四面体的体积和表面积计算程序,同时将其嵌套在魔方的类层级结构中。

  1. Solid抽象类:表示立体图形的抽象概念和方法,包括边长和表面积等属性和方法。

  2. Cube类:继承自Solid类,表示立方体的具体实现,通过getSurfaceArea()getVolume()方法计算立方体的表面积和体积。

  3. RegularPyramid类:继承自Solid类,表示正四面体的具体实现,通过getSurfaceArea()getVolume()方法计算正四面体的表面积和体积。

  4. RubikCube抽象类:表示魔方的抽象概念和方法,包括颜色、层数和立体图形等属性和方法。

  5. SquareCube类:继承自RubikCube类,表示立方魔方的具体实现,通过getTotalSurfaceArea()getTotalVolume()方法计算立方魔方的表面积和体积。

  6. RegularPyramidCube类:继承自RubikCube类,表示正四面体魔方的具体实现,通过getTotalSurfaceArea()getTotalVolume()方法计算正四面体魔方的表面积和体积。

  7. main方法:程序入口,通过标准输入读取颜色、层数和边长等信息,并创建对应的魔方对象。然后调用display方法输出魔方的颜色、表面积和体积等信息。

  8. display方法:用于输出魔方的颜色、表面积和体积等信息。

总体而言,该代码实现了一个简单的魔方体积和表面积计算程序,通过面向对象的方式对立方体和正四面体进行抽象和处理,实现了魔方表面积和体积的计算。代码结构清晰,逻辑简洁,但可能还有一些可以改进的地方,比如加入异常处理、优化算法等。

(4)魔方排序问题

在魔方问题的基础上,重构类设计,实现列表内魔方的排序功能(按照魔方的体积进行排序)。

提示:题目中RubikCube类要实现Comparable接口。

其中,Main类源码如下(可直接拷贝使用):

 
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        String color;
        int layer;
        double side;
        RubikCube cube;
        
        ArrayList<RubikCube> list = new ArrayList<>();
        
        int choice = input.nextInt();
        
        while(choice != 0) {
            switch(choice) {
            case 1://SquareCube
                color = input.next();
                layer = input.nextInt();
                side = input.nextDouble();
                cube = new SquareCube(color, layer,new Cube(side)); 
                list.add(cube);
                break;
            case 2://RegularPyramidCube
                color = input.next();
                layer = input.nextInt();
                side = input.nextDouble();
                cube = new RegularPyramidCube(color, layer,new RegularPyramid(side)); 
                list.add(cube);
                break;
            }
            choice = input.nextInt();
        }
        
        list.sort(Comparator.naturalOrder());//正向排序
        
        for(int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i).getColor() + " " + 
        String.format("%.2f", list.get(i).getArea()) + " " + 
        String.format("%.2f", list.get(i).getVolume()) );
            System.out.println("");
        }            
    }    
}

输入格式:

输入魔方类型(1:正方体魔方;2:正三棱锥魔方;0:结束输入)

魔方颜色、魔方阶数、魔方单元正方体、正三棱锥边长

..循环..

输出格式:

按魔方体积升序输出列表中各魔方的信息(实型数均保留两位小数),输出样式参见输出样例。

输入样例:

在这里给出一组输入。例如:

1 blue 3 4.5
2 red 4 2.1
1 yellow 5 2.3
2 black 4 9.42
1 white 4 5.4423
0

输出样例:

在这里给出相应的输出。例如:

red 122.21 69.85
yellow 793.50 1520.88
blue 1093.50 2460.38
black 2459.14 6304.73
white 2843.39 10316.38
先给出代码:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

abstract class Solid {
protected double side;

public Solid(double side) {
this.side = side;
}

public abstract double getSurfaceArea();

public abstract double getVolume();
}

class Cube extends Solid {
public Cube(double side) {
super(side);
}

public double getSurfaceArea() {
return 6 * Math.pow(side, 2);
}

public double getVolume() {
return Math.pow(side, 3);
}
}

class RegularPyramid extends Solid {
public RegularPyramid(double side) {
super(side);
}

public double getSurfaceArea() {
double baseArea = (Math.sqrt(3) / 4) * Math.pow(side, 2);
double slantHeight = Math.sqrt(Math.pow(side, 2) - Math.pow(side / 2, 2));
double lateralArea = 3 * (side * slantHeight) / 2;
return baseArea + lateralArea;
}

public double getVolume() {
return (Math.pow(side, 3) * Math.sqrt(2)) / 12;
}
}

abstract class RubikCube implements Comparable<RubikCube> {
protected String color;
protected int layer;
protected Solid solid;

public RubikCube(String color, int layer, Solid solid) {
this.color = color;
this.layer = layer;
this.solid = solid;
}

public abstract double getTotalSurfaceArea();

public abstract double getTotalVolume();

public String getColor() {
return color;
}

public int compareTo(RubikCube other) {
return Double.compare(this.getTotalVolume(), other.getTotalVolume());
}
}

class SquareCube extends RubikCube {
public SquareCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

public double getTotalSurfaceArea() {
return solid.getSurfaceArea() * Math.pow(layer, 2);
}

public double getTotalVolume() {
return solid.getVolume() * Math.pow(layer, 3);
}
}

class RegularPyramidCube extends RubikCube {
public RegularPyramidCube(String color, int layer, Solid solid) {
super(color, layer, solid);
}

public double getTotalSurfaceArea() {
return solid.getSurfaceArea() * Math.pow(layer, 2);
}

public double getTotalVolume() {
return solid.getVolume() * Math.pow(layer, 3);
}
}

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);

String color;
int layer;
double side;
RubikCube cube;

ArrayList<RubikCube> list = new ArrayList<>();

int choice = input.nextInt();

while(choice != 0) {
switch(choice) {
case 1://SquareCube
color = input.next();
layer = input.nextInt();
side = input.nextDouble();
cube = new SquareCube(color, layer,new Cube(side));
list.add(cube);
break;
case 2://RegularPyramidCube
color = input.next();
layer = input.nextInt();
side = input.nextDouble();
cube = new RegularPyramidCube(color, layer,new RegularPyramid(side));
list.add(cube);
break;
}
choice = input.nextInt();
}

list.sort(Comparator.naturalOrder());

for(int i = 0; i < list.size(); i++) {
System.out.print(list.get(i).getColor() + " " +
String.format("%.2f", list.get(i).getTotalSurfaceArea()) + " " +
String.format("%.2f", list.get(i).getTotalVolume()) );
System.out.println("");
}
}
}

PowerDesigner分析:

 SourceMonitor分析:

 总结:

这段代码实现了一个立方体和正四面体魔方的体积和表面积计算程序。代码使用面向对象的思想,定义了抽象类Solid表示立体图形,包括边长和计算表面积和体积的抽象方法。

Cube类继承自Solid类,表示立方体,实现了计算表面积和体积的方法。

RegularPyramid类也继承自Solid类,表示正四面体,同样实现了计算表面积和体积的方法。

抽象类RubikCube表示魔方,包括颜色、层数和关联的立体图形等属性和方法。它继承了Comparable接口以实现对象之间的比较。

SquareCube类继承自RubikCube类,表示立方体魔方,实现了计算表面积和体积的方法。

RegularPyramidCube类继承自RubikCube类,表示正四面体魔方,同样实现了计算表面积和体积的方法。

Main类中,通过用户输入选择不同类型的魔方,并根据输入创建对应的魔方对象。然后将这些对象添加到list列表中,并根据体积进行排序。最后遍历列表,输出每个魔方的颜色、表面积和体积信息。

总之,该代码实现了一个简单的魔方体积和表面积计算程序,使用了面向对象的编程思想,结构清晰,逻辑简洁。

(4)销售步枪问题

前亚利桑那州境内的一位步枪销售商销售密苏里州制造的步枪机(lock)、枪托(stock)和枪管(barrel)。枪机卖45美元,枪托卖30美元,枪管卖25美元。销售商每月至少要售出一支完整的步枪,且生产限额是销售商在一个月内可销售70个枪机、80个枪托和90个枪管。

根据每个月的销售情况,计算销售商的佣金(提成)算法如下:

  • 不到(含)1000美元的部分为10%;

  • 1000(含)~1800美元的部分为15%;

  • 超过1800美元的部分为20%。

佣金程序生成月份销售报告,汇总销售商的销售总额和佣金。

编程要求:必须符合面向对象编程,且保证类设计的单一职责模式,使用面向过程编程判定0分。

提示:可以设置一个销售订单类。参考类图如下:

image.png

输入格式:

输入销售商每个月售出枪机、枪托、枪管的数量,可以用空格或者回车分隔。

输出格式:

分别输出销售商在该月的销售额和佣金,中间用空格分开。

输入样例1:

在这里给出一组输入。例如:

30 40 50

输出样例1:

在这里给出相应的输出。例如:

3800.00 620.00

输入样例2:
在这里给出一组输入。例如:

88 56 98

输出样例2:
在这里给出相应的输出。例如:

Wrong Format
先给出代码:

import java.util.*;
class GunPart {
private final double price;

public GunPart(double price) {
this.price = price;
}

public double getPrice() {
return price;
}
}

class SalesOrder {
private final GunPart lock;
private final GunPart stock;
private final GunPart barrel;
private final int lockQuantity;
private final int stockQuantity;
private final int barrelQuantity;

public SalesOrder(GunPart lock, GunPart stock, GunPart barrel, int lockQuantity, int stockQuantity, int barrelQuantity) {
this.lock = lock;
this.stock = stock;
this.barrel = barrel;
this.lockQuantity = lockQuantity;
this.stockQuantity = stockQuantity;
this.barrelQuantity = barrelQuantity;
}

public double calculateTotalSales() {
return (lock.getPrice() * lockQuantity) + (stock.getPrice() * stockQuantity) + (barrel.getPrice() * barrelQuantity);
}
}

class CommissionCalculator {
private static final double RATE_LOW = 0.10;
private static final double RATE_MEDIUM = 0.15;
private static final double RATE_HIGH = 0.20;

public double calculateCommission(double sales) {
if (sales <= 1000) {
return sales * RATE_LOW;
} else if (sales <= 1800) {
return (1000 * RATE_LOW) + ((sales - 1000) * RATE_MEDIUM);
} else {
return (1000 * RATE_LOW) + (800 * RATE_MEDIUM) + ((sales - 1800) * RATE_HIGH);
}
}
}

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int lockQuantity = scanner.nextInt();
int stockQuantity = scanner.nextInt();
int barrelQuantity = scanner.nextInt();

// Close the scanner as it's no longer needed
scanner.close();


if (lockQuantity > 70 || stockQuantity > 80 || barrelQuantity > 90 || lockQuantity < 1 || stockQuantity < 1 || barrelQuantity < 1) {
System.out.println("Wrong Format");
} else {

GunPart lock = new GunPart(45);
GunPart stock = new GunPart(30);
GunPart barrel = new GunPart(25);


SalesOrder order = new SalesOrder(lock, stock, barrel, lockQuantity, stockQuantity, barrelQuantity);

double totalSales = order.calculateTotalSales();
CommissionCalculator calculator = new CommissionCalculator();
double commission = calculator.calculateCommission(totalSales);


System.out.printf("%.2f %.2f%n", totalSales, commission);
}
}
}

PowerDesigner分析:

 SourceMonitor分析:

 总结:

这段代码是一个简单的销售订单计算程序。它包含了三个类:GunPartSalesOrderCommissionCalculator

GunPart类表示枪械零件,具有私有的价格属性和获取价格的方法。

SalesOrder类表示销售订单,包含了锁、库存和枪管三种零件的对象,以及对应的数量。它提供了一个计算总销售额的方法。

CommissionCalculator类是一个佣金计算器,它根据销售额的不同范围计算佣金。它使用了静态常量来定义不同范围的佣金率,并提供了一个计算佣金的方法。

Main类中,首先从用户输入中获取锁、库存和枪管的数量。然后根据输入的数量判断是否符合要求,如果不符合则输出"Wrong Format"。如果符合要求,则创建GunPart对象表示各个零件,并根据输入的数量创建一个SalesOrder对象。然后计算总销售额和佣金,并输出结果。

总结起来,这段代码实现了一个简单的销售订单计算程序。它使用了面向对象的编程思想,将不同的功能模块封装为不同的类,提高了代码的可读性和可维护性。通过输入零件数量,计算总销售额和佣金,并输出结果。

(5)课程成绩统计程序-3:

课程成绩统计程序-3在第二次的基础上修改了计算总成绩的方式,

要求:修改类结构,将成绩类的继承关系改为组合关系,成绩信息由课程成绩类和分项成绩类组成,课程成绩类组合分项成绩类,分项成绩类由成绩分值和权重两个属性构成。

完成课程成绩统计程序-2、3两次程序后,比较继承和组合关系的区别。思考一下哪一种关系运用上更灵活,更能够适应变更。

题目最后的参考类图未做修改,大家根据要求自行调整,以下内容加粗字体显示的内容为本次新增的内容。

某高校课程从性质上分为:必修课、选修课、实验课,从考核方式上分为:考试、考察、实验。

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

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

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

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

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。实验课的成绩必须为实验。

1、输入:

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

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

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

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

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

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

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

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

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

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

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

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

以上信息的相关约束:

1)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

2)学号由8位数字组成

3)姓名不超过10个字符

4)课程名称不超过10个字符

5)不特别输入班级信息,班级号是学号的前6位。

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)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

6)如果解析实验课程信息时,输入的分项成绩数量值和分项成绩权重的个数不匹配,输出:课程名称+" : number of scores does not match"

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

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

参考类图(与第一次相同,其余内容自行补充):

fdada4ca193119ee30531ab82ffebbfa_9dbcf4e8-1627-4cf6-8764-cccf44947e2a.png

输入样例1:

在这里给出一组输入。例如:

java 实验 实验 4 0.2 0.3 0.2 0.3
end

输出样例1:

在这里给出相应的输出。例如:

java has no grades yet

输入样例2:

在这里给出一组输入。例如:

java 实验 实验 4 0.2 0.3 0.2
end

输出样例2:

在这里给出相应的输出。例如:

java : number of scores does not match

输入样例3:

在这里给出一组输入。例如:

java 实验 实验 4 0.2 0.3 0.2 0.1
end

输出样例3:

在这里给出相应的输出。例如:

java : weight value error

输入样例4:

在这里给出一组输入。例如:

java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100
end

输出样例4:

在这里给出相应的输出。例如:

20201116 张三 86
java 86
202011 86

输入样例5:

在这里给出一组输入。例如:

java 实验 实验 4 0.2 0.3 0.2 0.3
20201116 张三 java 70 80 90 100 80
end

输出样例5:

在这里给出相应的输出。例如:

20201116 张三 : access mode mismatch
20201116 张三 did not take any exams
java has no grades yet
202011 has no grades yet
先给出代码:

import java.util.*;
import java.text.*;
class Calculate_grades {
int stu_all_grades(Data_storage data_storage,String num){//单个学生总课程平均分计算 返回一个分数 1)
int count =0;//这个学生有几门课
int sum = 0;
for (Map.Entry<String, Score> entry : data_storage.stu__st_cour.get(num).gradeMap.entrySet()) {
Score value = entry.getValue();
if(Integer.parseInt(value.total_scores)>=0) {
count++;
sum += Integer.parseInt(value.total_scores);
}
}
if(count!=0)
return sum/count;
else
return -100;//没有参加任何考试
}
int[] single_course_grades(Data_storage data_storage,String name){ //2) 课程名
int count = 0;
int[] aver_grade = new int[3];//0:平时成绩 1:期末考试 2:总分平均
for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {//遍历选课类:num-选课类
StudentsAll_mes value = e.getValue();
for (Map.Entry<String, Score> entry : value.gradeMap.entrySet()) {//遍历选课类:course.name-Score
String key1 = entry.getKey();
Score value1 = entry.getValue();
if (key1.equals(name)) {
if(Integer.parseInt(value1.total_scores)>=0) {//总分为- 说明算成绩无效
count++;
aver_grade[2] += Integer.parseInt(value1.total_scores);
if (value1 instanceof Test_Score) {
if (Integer.parseInt(value1.total_scores) >= 0) {
aver_grade[0] += Integer.parseInt(((Test_Score) value1).normal_score);
aver_grade[1] += Integer.parseInt(((Test_Score) value1).end_score);
}
} else if (value1 instanceof Inspect_Score){
if (Integer.parseInt(value1.total_scores) >= 0) {
aver_grade[0] = -100;//不需要平时成绩
aver_grade[1] += Integer.parseInt(((Inspect_Score) value1).end_score);
}
}else if(value1 instanceof Lab_Score){
if(Integer.parseInt(value1.total_scores)>=0){
aver_grade[0] = -100;
aver_grade[1] += aver_grade[1] += Integer.parseInt(value1.total_scores);
}
}
}
}
}
}
if(count!=0) {
for (int i = 0; i < 3; i++) {
aver_grade[i] = aver_grade[i] / count;
}
}else {
for (int i = 0; i < 3; i++) {
aver_grade[i] = -100;
}
}
return aver_grade;
}
int Class_grades(Data_storage data_storage,String num){//3)
int sum = 0;
int count = 0;
for (Map.Entry<String, Student> mapEntry : data_storage.classes.get(num).students.entrySet()) {//班级号-Student类
Student value = mapEntry.getValue();//遍历这个班级的所有学生
for (Map.Entry<String, StudentsAll_mes> e : data_storage.stu__st_cour.entrySet()) {//stu_num-选课类
String key1 = e.getKey();//遍历学生的选课类 学号
StudentsAll_mes value1 = e.getValue();
if (key1.equals(value.num)) {//选课类中 跟输入的学号一样
for (Map.Entry<String, Score> entry : value1.gradeMap.entrySet()) {//该num所有成绩遍历
Score gra = entry.getValue();
if(Integer.parseInt(gra.total_scores)>=0) {//有效才算
sum += Integer.parseInt(gra.total_scores);
count++;
}
}
}
}
}
if(count!=0)
return sum/count;
else
return -100;
}
void final_score(Data_storage data_storage,String num){//计算没门课的成绩 学号
data_storage.stu__st_cour.get(num).gradeMap.forEach((key,value)->{//学号 成绩
if(value instanceof Test_Score&&((Test_Score) value).normal_score.matches("\\d+")&&((Test_Score) value).end_score.matches("\\d+")) {
double tem = ((Test_Course) data_storage.courses.get(key)).normal_weight*Integer.parseInt(((Test_Score) value).normal_score);
double tem1 = ((Test_Course) data_storage.courses.get(key)).end_weight*Integer.parseInt(((Test_Score) value).end_score);
value.total_scores = String.valueOf((int)(tem+tem1));
}else if(value instanceof Inspect_Score&&((Inspect_Score) value).end_score.matches("\\d+")){
value.total_scores = ((Inspect_Score) value).end_score;
}else if(value instanceof Lab_Score&&((Lab_Score) value).lab_num.matches("\\d+")){
float sum = 0;
int i=0;
for (Integer score : ((Lab_Score) value).scores) {
sum+= score* ((Lab_Course) data_storage.courses.get(key)).weights.get(i);
i++;
}
value.total_scores = String.valueOf((int)sum);
}
});
}
}
class Class {
String num;
TreeMap<String, Student> students = new TreeMap<>(); //班级里的学生 学号 学生
Class(String num){
this.num = num;
}
}
class Course {
String type;
String test_way;
String name;
Course(String name,String type, String test_way){
this.type = type;
this.name = name;
this.test_way = test_way;
}
}
class Inspect_Course extends Course{
Inspect_Course(String name, String type, String test_way) {
super(name, type, test_way);
}
}
class Test_Course extends Course{
double normal_weight;
double end_weight;

Test_Course(String name, String type, String test_way,String normal_weight,String end_weight) {
super(name, type, test_way);
this.normal_weight = Float.parseFloat(normal_weight);
this.end_weight = Float.parseFloat(end_weight);
}
}
class Lab_Course extends Course{
int sub_scores_num;
ArrayList<Float> weights = new ArrayList<>();
Lab_Course(String name, String type, String test_way,String line) {
super(name, type, test_way);
String[] lines = line.split(" ");
sub_scores_num = Integer.parseInt(lines[3]);
for(int i=4;i<lines.length; i++){
weights.add(Float.parseFloat(lines[i]));
}
}
}
class Data_storage {
TreeMap<String , Course> courses;//课程 k:课程名 v:课程
TreeMap<String, Class> classes = new TreeMap<>();//班级 k:班级号V:班级
TreeMap<String, StudentsAll_mes> stu__st_cour;//选课类学生类结合 k:学号 v:选课类
InAndOut_put output = new InAndOut_put();
Data_storage(){
//学生和选课类结合
stu__st_cour = new TreeMap<>(Data_storage::compare);//重写排序
courses = new TreeMap<>(Data_storage::compare);
}

private static int compare(String o1, String o2) {

try {
Comparator<Object> comparator = Collator.getInstance(Locale.CHINA);
if (comparator.compare(o1, o2) < 0) {
return -1;
} else if (comparator.compare(o1, o2) > 0) {
return 1;
}
} catch (Exception ignored) {
}
return 0;
}
void setInspectCourses(String name, String type, String test_way){
if(!courses.containsKey(name)) {
courses.put(name, new Inspect_Course(name, type, test_way));
}
}
void setTestCourses(String name, String type, String test_way,String normal_weight, String end_weight){
if(!courses.containsKey(name)) {
courses.put(name, new Test_Course(name, type, test_way,normal_weight, end_weight));
}
}
void setLabCourses(String name, String type, String test_way,String line){
if(!courses.containsKey(name)) {
courses.put(name, new Lab_Course(name, type, test_way,line));
}
}
void setClasses(String num){
if(!classes.containsKey(num)) {
classes.put(num, new Class(num));
}
}
void setStudents(String clas_num, String name, String num){//班级号 姓名 学号
if(classes.containsKey(clas_num)){
if(!classes.get(clas_num).students.containsKey(num))
classes.get(clas_num).students.put(num,new Student(name,num));
}
}
void setStu__st_courAndMap(String num,String course,String normal_score,String end_score){//添加选课类 学生姓名 课程名称 分数
if(!stu__st_cour.containsKey(num)){
stu__st_cour.put(num,new StudentsAll_mes(num,course,normal_score,end_score));
}
else{
stu__st_cour.get(num).setGradeMap(course,normal_score,end_score);
}
}
void setStu__st_courAndMap(String num,String course,String end_score){
if(!stu__st_cour.containsKey(num)){
stu__st_cour.put(num,new StudentsAll_mes(num,course,end_score));
}
else{
stu__st_cour.get(num).setGradeMap(course,end_score);
}
}
void set_lab_grades(String stu_num,String course,String lab_num,String grades){
ArrayList<Integer> scores = new ArrayList<>();
String[] tem = grades.split(" ");
for(int i=3;i<tem.length;i++){
if(tem[i].matches("\\d+"))
scores.add(Integer.parseInt(tem[i]));
}
if(!stu__st_cour.containsKey(stu_num)){
StudentsAll_mes tem_stu_mes = new StudentsAll_mes();
tem_stu_mes.set_lab_stu_mes(stu_num,course,lab_num,scores);
stu__st_cour.put(stu_num,tem_stu_mes);
}else{
stu__st_cour.get(stu_num).set_lab_gradeMap(course,lab_num,scores);
}
}
}
class Input_Format {
String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修)\\s考试\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s选修\\s考察$";
String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s实验\\s实验\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){3,9}$";
String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4E00-\\u9FA5A-Za-z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9 ]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){2,9}$";
boolean isEnd = true;//结束标志
String[] strings;
void inputProcessing(String line,Data_storage data_storage) {
lineProcessing(line);//分割
data_storage.output.add_input(line);//存储
if(line.matches(regex_c_inspect)){
data_storage.setInspectCourses(strings[0],strings[1],strings[2]);
}else if(line.matches(regex_c_lab)){
data_storage.setLabCourses(strings[0],strings[1],strings[2],line);
}else if(line.matches(regex_c_test)){
data_storage.setTestCourses(strings[0],strings[1],strings[2],strings[3],strings[4]);//成绩信息
} else if(line.matches(regex_CS)||line.matches(regex_lab)){
data_storage.setClasses(strings[0].substring(0,6));
data_storage.setStudents(strings[0].substring(0, 6), strings[1], strings[0]);//学生的添加
if (data_storage.courses.containsKey(strings[2])) {//课程里有这个课
if (data_storage.courses.get(strings[2]).type.equals("选修")) {//
if (data_storage.courses.get(strings[2]).test_way.equals("考试")&&strings.length == 5) {
data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3], strings[4]);
}else if(data_storage.courses.get(strings[2]).test_way.equals("考察")&&strings.length==4){
data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3]);
} else {
data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
}
} else if (data_storage.courses.get(strings[2]).type.equals("必修")) {//
if (strings.length == 5) {
data_storage.setStu__st_courAndMap(strings[0], strings[2], strings[3],strings[4]);
} else {//无效
data_storage.setStu__st_courAndMap(strings[0], strings[2], "no access", "no access");
}
} else if(data_storage.courses.get(strings[2]).type.equals("实验")){
if(strings.length == 3+((Lab_Course) data_storage.courses.get(strings[2])).sub_scores_num){
data_storage.set_lab_grades(strings[0],strings[2], String.valueOf(((Lab_Course) data_storage.courses.get(strings[2])).sub_scores_num),line);
}else{
data_storage.set_lab_grades(strings[0],strings[2],"num error","no access");
}
}
}else{
data_storage.setStu__st_courAndMap(strings[0], strings[2], "not exist");
}
}
}
void lineProcessing(String line){
strings = line.split(" ");
}
}
class Inspect_Score extends Score{
String end_score;
Inspect_Score(String end_score) {
this.end_score = end_score;
}
}
class Output_Format {
Calculate_grades calculate = new Calculate_grades();
String regex_c_test = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s((\\d{1,2})|(1-9?))\\s((\\d{1,2})|(1-9?))$";
String regex_c_test_e = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s((0.\\d{1,2})|(1-9?))\\s((0.\\d{1,2})|(1-9?))$";
String regex_c_inspect = "[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)$";
String regex_c_lab = "^[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s(必修|选修|实验)\\s(考试|考察|实验)\\s[4-9]\\s((0.\\d{1,2})|(1-9?))(\\s((0.\\d{1,2})|(1-9?))){1,10}$";
String regex_CS = "^\\d{8}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s+[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s*((100)|(\\d{1,2})|(0))?\\s+((100)|(\\d{1,2})|(0))$";
String regex_lab = "^\\d{8}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s[\\u4e00-\\u9fa5a-zA-Z0-9]{1,10}\\s((100)|([1-9]\\d)|\\d)(\\s((100)|([1-9]\\d)|\\d)){1,20}$";
void outputProcessing(Data_storage data) {
data.classes.forEach((num,Class)-> Class.students.forEach((name, student)-> calculate.final_score(data,student.num)));
for(String i:data.output.input){
String[] tem = i.split(" ");
if(i.matches(regex_c_test_e)||i.matches(regex_c_test)||i.matches(regex_c_inspect)||i.matches(regex_c_lab)){
if(tem[1].equals("必修")&&(tem[2].equals("考察")||tem[2].equals("实验"))){
data.output.add_output(tem[0] + " : course type & access mode mismatch");
}else if(tem[1].equals("实验")&&!tem[2].equals("实验")) {
data.output.add_output(tem[0] + " : course type & access mode mismatch");
}else if(tem[1].equals("选修")&&tem[2].equals("实验")) {
data.output.add_output(tem[0] + " : course type & access mode mismatch");
}
if(tem[1].equals("实验")&&tem[2].equals("实验")) {
if(tem.length-4>=4&&tem.length - 4<=9) {
if (Integer.parseInt(tem[3]) != tem.length - 4) {
data.output.add_output(tem[0] + " : number of scores does not match");
data.courses.remove(tem[0]);
continue;
}
float tem_weight = 0;
for (int j = 4; j < tem.length; j++) {
tem_weight += Float.parseFloat(tem[j]);
}
if (Math.abs(tem_weight - 1) > 0.0001) {
data.output.add_output(tem[0] + " : weight value error");
data.courses.remove(tem[0]);
continue;
}
}else{
try {
if (Integer.parseInt(tem[3]) != tem.length - 4) {
data.output.add_output(tem[0] + " : number of scores does not match");
data.courses.remove(tem[0]);
continue;
}
} catch (Exception ignored) {

}
}
}if((tem[1].equals("必修")||tem[1].equals("选修"))&&tem[2].equals("考试")){
if(tem.length-3==2) {
float tem_weight = Float.parseFloat(tem[3]) + Float.parseFloat(tem[4]);
if (Math.abs(tem_weight - 1) > 0.0001) {
data.output.add_output(tem[0] + " : weight value error");
data.courses.remove(tem[0]);
}
}
}
}else if(i.matches(regex_CS)||i.matches(regex_lab)) {
if(!data.courses.containsKey(tem[2])){//不存在
data.output.add_output(tem[2]+" does not exist");
data.stu__st_cour.get(tem[0]).gradeMap.remove(tem[2]);
}else{
if(data.courses.get(tem[2]).type.equals("必修") && tem.length!=5) {//必修 但是只有期末成绩
data.output.add_output(tem[0]+" "+tem[1]+" : access mode mismatch");
}else if(data.courses.get(tem[2]).type.equals("选修")) {
if ((data.courses.get(tem[2]).test_way.equals("考试") && tem.length != 5) ||
(data.courses.get(tem[2]).test_way.equals("考察") && tem.length != 4))
data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
}else if(data.courses.get(tem[2]).type.equals("实验")){
if(data.courses.get(tem[2]).test_way.equals("实验")&&(tem.length-3<4||tem.length-3>9||tem.length-3!=((Lab_Course) data.courses.get(tem[2])).sub_scores_num))
data.output.add_output(tem[0] + " " + tem[1] + " : access mode mismatch");
}
}
}else if(!i.equals("end")){
data.output.add_output("wrong format");
}
}
data.classes.forEach((cla_num,Class1)->{//遍历所有班级
Class1.students.forEach((stu_num,student)->{
int tem=calculate.stu_all_grades(data,stu_num);
if(tem>=0)
data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+tem);
else
data.output.add_output(stu_num+" "+Class1.students.get(stu_num).name+" "+"did not take any exams");
});
});
data.courses.forEach((key,value)-> {
int[] tem = calculate.single_course_grades(data, key);
if (tem[0] < 0 && tem[1] < 0 && tem[2] < 0) {//三个为- 则没成绩
data.output.add_output(key + " has no grades yet");
}else {
if (value.type.equals("选修") || value.type.equals("必修") || value.type.equals("实验")) {
data.output.add_output(key + " " + tem[2]);
}
}
});
data.classes.forEach((num,Class)->{
int tem = calculate.Class_grades(data,num);
if(tem>=0) {
data.output.add_output(num + " " + tem);
}else
data.output.add_output(num+" has no grades yet");
});
}
void output_all(Data_storage data){
data.output.output.forEach(System.out::println);
}
}
abstract class Score {
String total_scores = "-100";
}
class Student {
String name;
String num;
Student(String name, String num) {
this.name = name;
this.num = num;
}
}
class StudentsAll_mes {
String num;//学生
TreeMap<String,Score> gradeMap =new TreeMap<>();
StudentsAll_mes(String stu_name, String course, String normal_score,String test_score){
this.num = stu_name;
gradeMap.put(course,new Test_Score(normal_score,test_score));
}
StudentsAll_mes(String stu_name, String course, String test_score){
this.num = stu_name;
gradeMap.put(course,new Inspect_Score(test_score));
}

public StudentsAll_mes() {

}
void set_lab_stu_mes(String stu_num,String course,String lab_num,ArrayList<Integer> scores){
this.num = stu_num;
gradeMap.put(course,new Lab_Score(lab_num,scores));
}
void set_lab_gradeMap(String course,String lab_num,ArrayList<Integer> scores){
if(!gradeMap.containsKey(course))
gradeMap.put(course,new Lab_Score(lab_num,scores));
}
void setGradeMap(String course, String normal_score,String test_score){
if(!gradeMap.containsKey(course))
gradeMap.put(course, new Test_Score(normal_score,test_score));
}
void setGradeMap(String course,String test_score){
if(!gradeMap.containsKey(course))
gradeMap.put(course,new Inspect_Score(test_score));
}

}
class Test_Score extends Score{
String normal_score;
String end_score;
Test_Score(String normal_score,String end_score) {
this.normal_score = normal_score;
this.end_score = end_score;
}
}
class Lab_Score extends Score {
String lab_num;//试验次数

ArrayList<Integer> scores;
Lab_Score(String lab_num,ArrayList<Integer> scores){
this.lab_num = lab_num;
this.scores = scores;
}
}
class InAndOut_put {
List<String> output = new ArrayList<>();
List<String> input = new ArrayList<>();
void add_output(String out){
output.add(out);
}
void add_input(String out){
input.add(out);
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Input_Format inputFormat = new Input_Format();//输入
Output_Format outputFormat = new Output_Format();//输出
Data_storage data_storage = new Data_storage();
while (inputFormat.isEnd){
String inputLine = scanner.nextLine();
if(inputLine.equals("end")){
inputFormat.isEnd = false;
break;
}
inputFormat.inputProcessing(inputLine,data_storage);
}
outputFormat.outputProcessing(data_storage);
outputFormat.output_all(data_storage);
}
}
class Food {
private String name;
private String type;
private double price;
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "Name: " + name + ", Age: " + age;
}
}
class Car {
private String brand;
private String model;
private int year;
public Car(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
}
public String toString() {
return "Brand: " + brand + ", Model: " + model + ", Year: " + year;
}
}
class Book {
private String title;
private String author;
private int year;
public Book(String title, String author, int year) {
this.title = title;
this.author = author;
this.year = year;
}
public String toString() {
return "Title: " + title + ", Author: " + author + ", Year: " + year;
}
}
class Animal {
private String species;
private String habitat;
public Animal(String species, String habitat) {
this.species = species;
this.habitat = habitat;
}
public String toString() {
return "Species: " + species + ", Habitat: " + habitat;
}
}
class Laptop {
private String brand;
private String model;
private double price;
public Laptop(String brand, String model, double price) {
this.brand = brand;
this.model = model;
this.price = price;
}
public String toString() {
return "Brand: " + brand + ", Model: " + model + ", Price: $" + price;
}
}
class Movie {
private String title;
private String director;
private int year;
public Movie(String title, String director, int year) {
this.title = title;
this.director = director;
this.year = year;
}
public String toString() {
return "Title: " + title + ", Director: " + director + ", Year: " + year;
}
}
class student {
private String name;
private int age;
private String major;
public student(String name, int age, String major) {
this.name = name;
this.age = age;
this.major = major;
}
public String toString() {
return "Name: " + name + ", Age: " + age + ", Major: " + major;
}
}
class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double balance) {
this.accountNumber = accountNumber;
this.balance = balance;
}
public String toString() {
return "Account Number: " + accountNumber + ", Balance: $" + balance;
}
}
class Country {
private String name;
private String capital;
private int population;
public Country(String name, String capital, int population) {
this.name = name;
this.capital = capital;
this.population = population;
}
public String toString() {
return "Name: " + name + ", Capital: ";
}
}

PowerDesigner分析:

 SourceMonitor分析:

 总结:

这段代码是一个Java程序,主要实现了学生成绩管理系统。它包括了输入格式的处理、成绩计算、数据存储、输出格式处理等功能。

  1. 数据结构与存储:使用了TreeMap来存储课程、班级以及学生选课信息,通过自定义的Data_storage类来统一管理这些数据,并采用InAndOut_put类来存储输入和输出信息。

  2. 成绩计算:定义了Calculate_grades类,其中包含了计算学生总平均分、单门课程平均分、班级平均分以及最终成绩的方法。

  3. 输入输出格式处理:Input_FormatOutput_Format类负责处理输入输出格式,检查输入的合法性,并将结果输出。

  4. 数据类:定义了课程类Course,学生类Student,成绩类Score等,来表示相关的数据信息。

  5. Main类:包含了程序的入口点main方法,从标准输入读取数据,并将结果输出到标准输出。

  6. 其他类:在代码末尾还定义了一些并未使用到的类,如FoodPersonCar等,可能是误入其中的其他代码片段。

总体来说,这段代码实现了学生成绩管理系统的基本功能,包括了数据的存储、成绩的计算和输入输出的处理。需要注意的是,代码中可能存在一些逻辑错误和未使用的类定义,需要进一步完善和清理。

三、总结

对于这三次的pta作业,我从中学到了不少。

学习Java是一项需要持续投入时间和精力的任务,以下是我对于Java学习的总结和建议:

  1. 建立良好的基础:Java语言本身就是非常严谨的,因此学习Java必须建立在扎实的编程基础上。建议先学习计算机基础知识、数据结构和算法等,然后再进入Java的学习。

  2. 刻意练习:学习编程最重要的就是练习。可以从一些简单的练手项目开始,逐渐增加难度。还可以参与一些开源项目,锻炼自己的编程能力。

  3. 多看源码:学习一个技术最好的方式就是看源码。Java是开源的,有很多优秀的开源框架和工具库,可以从中学到很多东西。比如Spring、MyBatis等。

  4. 认真对待异常处理:在Java编程中,异常处理非常重要。必须认真对待每一个异常,做好相应的处理。否则,一些小问题可能会引起严重的后果。

  5. 学习集成开发环境:Java开发离不开IDE,建议学习和掌握一些主流的IDE,如Eclipse、IntelliJ IDEA等。这些工具可以帮助你提高效率,减少出错。

  6. 参与社区:Java社区是非常活跃的,有很多技术讨论和交流。可以参与一些社区,比如CSDN、Stack Overflow等,交流学习经验和技术问题。

总之,学习Java需要持续的投入和努力,不断地学习和实践。只有不断地挑战自己,才能更好地掌握Java技术,提升自己的编程水平。

posted @ 2023-12-09 21:20  小小噬菌体  阅读(68)  评论(0)    收藏  举报