第三次Java大作业总结与分析
一、前言
在这一阶段的Java作业中,虽然题目量没有之前两次多,但是难度却增加了,我也没有全都做对,只能说能力还是需要提升。这一次作业主要考察继承与多态的综合运用,哈希树的运用。这都是Java里面比较难的部分,所以做起来十分费劲,花了很多时间但得不到很多分。对于继承和多态我勉强还可以做的来,能够做得大差不差,但是对于哈希树就比较头疼,不是很熟练,在里面统计单词的题也只是做对部分。我对于哈希树不熟练更多的是里面的方法不熟练,还需要多加练习才可以,下面是我对这次作业的整理和分析。
二、设计与分析
OOP08-7-2
输入格式:
在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:1 3 4 2 1 3 4 2 1 3 0
根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出Wrong Format。
如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
排序前的各图形类型及面积,格式为[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ],注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前;
输出分组后的图形类型及面积,格式为[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积],各组内格式为图形名称:面积值。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出;
各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
各组中面积之和的最大值输出,格式为The max area:面积值。
输入样例1:
在这里给出一组输入。例如:
1 5 3 2 0
输出样例1:
在这里给出相应的输出。例如:
Wrong Format
输入样例2:
在这里给出一组输入。例如:
4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 3.5
输出样例2:
在这里给出相应的输出。例如:
The original list:
[Trapezoid:1.14 Rectangle:3.22 Circle:98.52 Triangle:4.02 ]
The Separated List:
[Circle:98.52 ][Rectangle:3.22 ][Triangle:4.02 ][Trapezoid:1.14 ]
The Separated sorted List:
[Circle:98.52 ][Rectangle:3.22 ][Triangle:4.02 ][Trapezoid:1.14 ]
The max area:98.52
输入样例3:
在这里给出一组输入。例如:
2 1 2 1 1 3 3 4 4 1 1 1 2 1 0
2.3 3.5 2.5 4.5 2.1 2.6 8.5 3.2 3.1 3.6 8.5 7.5 9.1245 6.5 3.4 10.2 11.2 11.6 15.4 5.8 2.13 6.2011 2.5 6.4 18.65
输出样例3:
在这里给出相应的输出。例如:
The original list:
[Rectangle:8.05 Circle:19.63 Rectangle:9.45 Circle:21.24 Circle:226.98 Triangle:4.65 Triangle:29.80 Trapezoid:50.49 Trapezoid:175.56 Circle:105.68 Circle:14.25 Circle:120.81 Rectangle:16.00 Circle:1092.72 ]
The Separated List:
[Circle:19.63 Circle:21.24 Circle:226.98 Circle:105.68 Circle:14.25 Circle:120.81 Circle:1092.72 ][Rectangle:8.05 Rectangle:9.45 Rectangle:16.00 ][Triangle:4.65 Triangle:29.80 ][Trapezoid:50.49 Trapezoid:175.56 ]
The Separated sorted List:
[Circle:1092.72 Circle:226.98 Circle:120.81 Circle:105.68 Circle:21.24 Circle:19.63 Circle:14.25 ][Rectangle:16.00 Rectangle:9.45 Rectangle:8.05 ][Triangle:29.80 Triangle:4.65 ][Trapezoid:175.56 Trapezoid:50.49 ]
The max area:1601.31
输入样例4:
在这里给出一组输入。例如:
1 1 3 0
6.5 12.54 3.6 5.3 6.4
输出样例4:
在这里给出相应的输出。例如:
The original list:
[Circle:132.73 Circle:494.02 Triangle:9.54 ]
The Separated List:
[Circle:132.73 Circle:494.02 ][][Triangle:9.54 ][]
The Separated sorted List:
[Circle:494.02 Circle:132.73 ][][Triangle:9.54 ][]
The max area:626.75
代码长度限制
10 KB
时间限制
400 ms
内存限制
64 MB
源码:
点击查看代码
import java.util.*;
public class Main {
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();
}
}
abstract class Shape{
private String shapeName;
public Shape(String shapeName) {
this.shapeName = shapeName;
}
public Shape() {
}
public String getShapeName() {
return shapeName;
}
public abstract double getArea();
public abstract boolean validate();
public String toString(){
return shapeName;
}
}
class Circle extends Shape{
private double radius;
public Circle(double radius) {
super("Circle");
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public boolean validate() {
return radius > 0;
}
}
class Rectangle extends Shape{
private double width;
private double length;
public Rectangle(double width, double length) {
super("Rectangle");
this.width = width;
this.length = length;
}
@Override
public double getArea() {
return width * length;
}
@Override
public boolean validate() {
return width > 0 && length > 0;
}
}
class Triangle extends Shape{//三角形
private double side1;
private double side2;
private double side3;
public Triangle(double side1, double side2, double side3) {
super("Triangle");
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
@Override
public double getArea() {
double s = (side1 + side2 + side3) / 2.0;
return Math.sqrt(s*(s-side1)*(s-side2)*(s-side3));
}
@Override
public boolean validate() {
return side1 > 0 && side2 > 0 && side3 > 0 && (side1 + side2 > side3)
&& (side2 + side3 > side1) && (side3 + side1 > side2);
}
}
class Trapezoid extends Shape{//梯形
private double topSide;
private double bottomSide;
private double height;
public Trapezoid( double topSide, double bottomSide, double height) {
super("Trapezoid");
this.topSide = topSide;
this.bottomSide = bottomSide;
this.height = height;
}
@Override
public double getArea() {
return (topSide + bottomSide) * height / 2.0;
}
@Override
public boolean validate() {
return topSide > 0 && bottomSide > 0 && height > 0;
}
}
interface Comparable{
public int compareTo(Card card);
}
class Card implements Comparable{
private Shape shape;
public Card(Shape shape) {
this.shape = shape;
}
public Card() {
}
public Shape getShape() {
return shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
@Override
public int compareTo(Card card) {
if(this.shape.getArea() > card.shape.getArea()){
return -1;
}
else if(this.shape.getArea() < card.shape.getArea()){
return 1;
}
else
return 0;
}
}
class DealCardList{
ArrayList<Card> cardList = new ArrayList<Card>();
public DealCardList(ArrayList<Integer> list) {
for(int i:list) {
if(i==1) {
double r = Main.input.nextDouble();
Circle circle = new Circle(r);
Card card = new Card(circle);
cardList.add(card);
}
else if(i==2) {
double weight = Main.input.nextDouble();
double height = Main.input.nextDouble();
Rectangle rectangle = new Rectangle(weight,height);
Card card = new Card(rectangle);
cardList.add(card);
}
else if(i==3) {
double side1= Main.input.nextDouble();
double side2= Main.input.nextDouble();
double side3= Main.input.nextDouble();
Triangle triangle = new Triangle(side1,side2,side3);
Card card = new Card(triangle);
//Card a =new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble());
cardList.add(card);
}else if(i==4) {
double topSide= Main.input.nextDouble();
double bottomSide= Main.input.nextDouble();
double height= Main.input.nextDouble();
Trapezoid trapezoid = new Trapezoid(topSide,bottomSide,height);
Card card = new Card(trapezoid);
cardList.add(card);
}
}
}
public DealCardList() {
}
public boolean validate(){
for (int i = 0; i < cardList.size(); i++) {
if(!cardList.get(i).getShape().validate()){
return false;
}
}
return true;
}
public void cardSort(){
Collections.sort(cardList,Card::compareTo);
}
public double getAllArea(){
double sum = 0;
for (int i = 0; i < cardList.size(); i++) {
sum += cardList.get(i).getShape().getArea();
}
return sum;
}
public void showResult(){
double[] sum = new double[4];
System.out.println("The original list:");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ",cardList.get(i).getShape().getArea());
}
System.out.print("]");
System.out.println();
System.out.println("The Separated List:");
//cardSort();
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Circle")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
}
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Rectangle")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
}
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Triangle")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
}
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Trapezoid")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
}
}
System.out.print("]");
System.out.println();
System.out.println("The Separated sorted List:");
cardSort();
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Circle")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
sum[0] += cardList.get(i).getShape().getArea();
}
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Rectangle")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
sum[1] += cardList.get(i).getShape().getArea();
}
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Triangle")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
sum[2] += cardList.get(i).getShape().getArea();
}
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < cardList.size(); i++) {
if(Objects.equals(cardList.get(i).getShape().getShapeName(), "Trapezoid")) {
System.out.print(cardList.get(i).getShape().getShapeName() + ":");
System.out.printf("%.2f ", cardList.get(i).getShape().getArea());
sum[3] += cardList.get(i).getShape().getArea();
}
}
System.out.print("]");
System.out.println();
System.out.print("The max area:");
Arrays.sort(sum);
System.out.printf("%.2f",sum[3]);
}
}
我的类图

我的思路:
先是根据题目要求写完所有的类,再去写主方法。题目的难点就是主方法的写法,其实也不是很难。根据题目提示写出DealCardList类用来处理输入内容和进行输出,里面就是依据案例输入来书写方法,不算很难,有很多重复的东西,循环比较多,有的还要计算总数,这里用到链表可以做起来非常轻松:ArrayList<Card> cardList = new ArrayList<Card>();这里的链表里面的Card类是所有图形的父类,这样就可以写多态来创建对象,减去了很多繁琐的内容。
输出结果:

OOP09-7-1
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
Java中共有53个关键字(自行百度)
从键盘输入一段源码,统计这段源码中出现的关键字的数量
注释中出现的关键字不用统计
字符串中出现的关键字不用统计
统计出的关键字及数量按照关键字升序进行排序输出
未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志
输出格式:
当未输入源码时,程序输出Wrong Format
当没有统计数据时,输出为空
当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为数量\t关键字
输入样例:
在这里给出一组输入。例如:
//Test public method
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
exit
输出样例:
在这里给出相应的输出。例如:
1 float
3 if
2 int
2 new
2 public
3 this
2 throw
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
源码:
点击查看代码
import java.util.*;
public class Main {
private final static Set<String> keywordString = 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"));
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int i = 0;
Set<String> codeSet = new LinkedHashSet<>();
if (!input.hasNext()) {
// 判断输入是否为空,为空则输出错误并退出
System.out.println("Wrong Format");
System.exit(0);
}
while (true) {
String line = input.nextLine();
// 若出现exit则结束输入
if (line.equals("exit")) {
break;
}
// 若该行有数据则将其输入数据存入集合
if (!line.matches("\\s*")){
i++;
line = line + " line: " + i;
codeSet.add(line + "\n");
}
}
if (codeSet.isEmpty()) {
// 判断是否无代码输入
System.out.println("Wrong Format");
System.exit(0);
}
// 处理输入的代码
String code = dealWithCode(codeSet);
Map<String, Integer> resultMap = new TreeMap<>();
// 获取结果
resultMap = countKeywords(code);
for (Map.Entry<String, Integer> entry : resultMap.entrySet()) {
System.out.println(entry.getValue() + "\t" + entry.getKey());
}
}
/**
* 处理输入的代码
*/
public static String dealWithCode(Set<String> codeSet) {
String code = codeSet.toString();
// 删去字符串
code = code.replaceAll("\".*\"", " ");
// 删去单行注释
code = code.replaceAll("//.*\n"," ");
// 删去多行注释
code = code.replaceAll("/\\*(.|\n)*?\\*/"," ");
// 替换等号
code = code.replaceAll("=", "A");
// 删去无关的字符
code = code.replaceAll("[^a-zA-Z]", " ");
// 将多个空格替换为单个空格以便分割
code = code.replaceAll(" +", " ");
return code;
}
/**
* 统计每个关键字出现次数并存入Map中
*/
public static Map<String, Integer> countKeywords(String code) {
Map<String, Integer> resultMap = new TreeMap<>();
// 将输入并处理后的代码分割
String[] words = code.split(" ");
for (String keyword : keywordString) {
int count = 0;
// 遍历统计
for (String word : words) {
if (word.equals(keyword)) {
count++;
}
}
if (count > 0) {
resultMap.put(keyword, count);
}
}
return resultMap;
}
}
类图:

我的思路:
我一开始也没有什么头绪,听了老师上课讲解之后还是有些不太懂,最后都是查阅资料之后才懂怎么去做。首先先把所有的关键词写出来做成一个字符数组,之后把这个数组存入哈希集,利用哈希树来对里面的词进行计数,如果有那么就+1。里面的难点就是如何对标注代码进行区分,我也是这里没有做好,所以这道题的分数很低,上面正确代码也是受教他人来的,我主要就是判断标注时没有使用正则表达式,导致我写起来十分繁琐而且存在问题,上述代码就把它们在同一个方法里,一次性全部解决,更加简洁而且正确。
运行结果:

OOP10-7-1
某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。
考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩0.3+期末成绩0.7。
考察的总成绩直接等于期末成绩
必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。
1、输入:
包括课程、课程成绩两类信息。
课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。
课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式
课程性质输入项:必修、选修
考核方式输入选项:考试、考察
课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩
课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩
以上信息的相关约束:
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)成绩平均分只取整数部分,小数部分丢弃
输入样例1:
仅有课程。例如:
java 必修 考试
数据结构 选修 考试
形式与政治 选修 考察
end
输出样例1:
在这里给出相应的输出。例如:
java has no grades yet
数据结构 has no grades yet
形式与政治 has no grades yet
输入样例2:
单门考试课程 单个学生。例如:
java 必修 考试
20201103 张三 java 20 40
end
输出样例2:
在这里给出相应的输出。例如:
20201103 张三 34
java 20 40 34
202011 34
输入样例3:
单门考察课程 单个学生。例如:
java 选修 考察
20201103 张三 java 40
end
输出样例3:
在这里给出相应的输出。例如:
20201103 张三 40
java 40 40
202011 40
输入样例4:
考试课程 单个学生 不匹配的考核方式。例如:
java 必修 考试
20201103 张三 java 20
end
输出样例4:
在这里给出相应的输出。例如:
20201103 张三 : access mode mismatch
20201103 张三 did not take any exams
java has no grades yet
202011 has no grades yet
输入样例5:
单门课程,单个学生,课程类型与考核类型不匹配。例如:
java 必修 考察
20201103 张三 java 40
end
输出样例5:
在这里给出相应的输出。例如:
java : course type & access mode mismatch
java does not exist
20201103 张三 did not take any exams
202011 has no grades yet
输入样例6:
单门课程,多个学生。例如:
java 选修 考察
20201103 李四 java 60
20201104 王五 java 60
20201101 张三 java 40
end
输出样例6:
在这里给出相应的输出。例如:
20201101 张三 40
20201103 李四 60
20201104 王五 60
java 53 53
202011 53
输入样例7:
单门课程,单个学生,课程类型与考核类型不匹配。例如:
形式与政治 必修 考试
数据库 选修 考试
java 选修 考察
数据结构 选修 考察
20201103 李四 数据结构 70
20201103 李四 形式与政治 80 90
20201103 李四 java 60
20201103 李四 数据库 70 78
end
输出样例7:
在这里给出相应的输出。例如:
20201103 李四 73
java 60 60
数据结构 70 70
数据库 70 78 75
形式与政治 80 90 87
202011 73
输入样例8:
单门课程,单个学生,成绩越界。例如:
数据结构 选修 考察
20201103 李四 数据结构 101
end
输出样例8:
在这里给出相应的输出。例如:
wrong format
数据结构 has no grades yet
输入样例9:
多门课程,多个学生,多个成绩。例如:
形式与政治 必修 考试
数据库 选修 考试
java 选修 考察
数据结构 选修 考察
20201205 李四 数据结构 70
20201103 李四 形式与政治 80 90
20201102 王五 java 60
20201211 张三 数据库 70 78
end
输出样例9:
在这里给出相应的输出。例如:
20201102 王五 60
20201103 李四 87
20201205 李四 70
20201211 张三 75
java 60 60
数据结构 70 70
数据库 70 78 75
形式与政治 80 90 87
202011 73
202012 72
代码长度限制
16 KB
时间限制
1000 ms
内存限制
64 MB
我的代码:
点击查看代码
import java.text.Collator;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String input = s.nextLine();
Input handle=new Input();
while (!input.equals("end")) {
handle.parseInput(input);//处理数据
input = s.nextLine();
}
handle.display();//输出
}
}
class Input{//处理类
ArrayList<Student> students=new ArrayList<>();//临时存储学生信息
ArrayList<Course> courses=new ArrayList<>();//临时存储课程信息
ArrayList<Class> classes=new ArrayList<>();//临时存储班级信息
ArrayList<ChooseCourse> listChooseCourse = new ArrayList<>();//存储选课信息
public void parseInput(String str){
//用于判断课程信息的正确
String courseStr = "\\S{1,10}"+" " + "(选修|必修)" + " " + "(考试|考察)";
//用于判断分数信息的正确
String score1 = "[0-9]{8}" + " " + "\\S{1,10}" + " " + "\\S{1,10}" + " "+ "([1-9]?[0-9]|100)";
String score2 = "[0-9]{8}" + " " + "\\S{1,10}" + " " + "\\S{1,10}" + " "+"([1-9]?[0-9]|100)" + " " + "([1-9]?[0-9]|100)";
//根据正则表达式来判断是否正确
//符合课程信息条件
if(str.matches(courseStr))
inputCourse(str);
//符合分数信息条件
else if(str.matches(score1) ||str.matches(score2))
inputGrade(str);
//不符合输入信息格式
else
System.out.println("wrong format");
}
public void inputCourse(String str){//输入课程
String parts[]=str.split(" ");
String courseName=parts[0];//课程名称
String type=parts[1];//课程的性质(选修或者必修
String testType=parts[2];//课程考核的方式(考试或者考察
Course course=new Course(courseName,type,testType);
if(checkCourse(course)){//存在就不添加
if(searchCourse(courseName)==null)
courses.add(course);
}
}
public void inputGrade(String str){//输入成绩,在所有的课程输入完之后再执行的
String parts[]=str.split(" ");
String stuId= parts[0];//学生学号
String classID= parts[0].substring(0,6);//班级号
String name=parts[1];//学生名称
String courseName=parts[2];//课程名字
//如果该班级第一次出现
if(searchClass(classID)==null){
Class cla=new Class(classID);
classes.add(cla);
}
Student stu=new Student(classID,stuId,name);
if(!searchStudent(stuId))
students.add(stu);//将学生加入列表中
//如果课程为空,就输出。。。。
if(searchCourse(courseName)==null){
System.out.println(courseName+" "+"does not exist");
}
//当课程存在时
else if(searchCourse(courseName)!=null){
Course course=searchCourse(courseName);
//考察的情况
if(parts.length==4&&course.testType.equals("考察")){
int exam= Integer.parseInt(parts[3]);
AssessGrade assessGrade=new AssessGrade(exam);
ChooseCourse chooseCourse=new ChooseCourse(course,stu,assessGrade);
if(!searchChooseCourse(name,courseName))
listChooseCourse.add(chooseCourse);
}
//考试的情况
else if(parts.length==5&&course.testType.equals("考试")){
int pinshi= Integer.parseInt(parts[3]);
int exam= Integer.parseInt(parts[4]);
ExamGrade examGrade=new ExamGrade(pinshi,exam);
ChooseCourse chooseCourse=new ChooseCourse(course,stu,examGrade);
listChooseCourse.add(chooseCourse);
}
else{
System.out.println(stuId+" "+name+" "+": access mode mismatch");
}
}
}
public boolean checkCourse(Course course){
boolean flag = false;//判断必修选修和考试考察格式之间是否对应正确
if(course.getType().equals("必修")&&course.getTestType().equals("考试"))
flag = true;
else if(course.getType().equals("选修")&&(course.getTestType().equals("考试")||course.getTestType().equals("考察")))
flag = true;
if(flag)
return true;
else {
System.out.println(course.getCourseName() + " : course type & access mode mismatch");
return false;
}
}
public Class searchClass(String classId){
for(Class cls:classes){
if(cls.getClassId().equals(classId))
return cls;
}
return null;
}
public Course searchCourse(String name){
for(Course course:courses){
if(course.getCourseName().equals(name))
return course;
}
return null;
}
public boolean searchStudent(String id){
for(Student stu:students){
if(stu.getId().equals(id))
return true;
}
return false;
}
//查找是否有重复选课成绩
public boolean searchChooseCourse(String stuName,String courseName){
for(ChooseCourse cs:listChooseCourse){
if(cs.student.getStuName().equals(stuName)&&cs.course.getCourseName().equals(courseName))
return true;
}
return false;
}
public void displayStudents(){//输出学生信息
Collections.sort(students);
for(int i=0;i<students.size();i++){
Student stu=students.get(i);
//从选课信息中提取学生学号相对的选课信息
ArrayList<ChooseCourse> stuCourseSelects=getStudentSelects(stu.getId());
if(stuCourseSelects.size()!=0) {
System.out.println(stu.getId()+" "+stu.getStuName()+" "+getAvgSumScore(stuCourseSelects));
}
else if(stuCourseSelects.size()==0){
System.out.println(stu.getId()+" "+stu.getStuName()+" "+"did not take any exams");
}
}
}
public void displayCourses(){
Collections.sort(courses);
for(int i=0;i<courses.size();i++){
Course course=courses.get(i);
ArrayList<ChooseCourse> stuCourseSelects=getCourseSelects(course.getCourseName());
if(stuCourseSelects.size()!=0){
if(course.testType.equals("考试"))
System.out.println(course.getCourseName()+" "+getAvgPinshiScore(stuCourseSelects)+" "+getAvgExamScore(stuCourseSelects)+" "+getAvgSumScore(stuCourseSelects));
if(course.testType.equals("考察"))
System.out.println(course.getCourseName()+" "+getAvgExamScore(stuCourseSelects)+" "+getAvgSumScore(stuCourseSelects));
}
else if(stuCourseSelects.size()==0){
System.out.println(course.courseName+" "+"has no grades yet");
}
}
}
public void displayClasses(){
Collections.sort(classes);
for(int i=0;i<classes.size();i++){
Class cls=classes.get(i);
ArrayList<ChooseCourse> stuCourseSelects=getClassSelects(cls.getClassId());
if(stuCourseSelects.size()!=0){
System.out.println(cls.getClassId()+" "+getAvgSumScore(stuCourseSelects));
}
else if(stuCourseSelects.size()==0){
System.out.println(cls.getClassId()+" "+"has no grades yet");
}
}
}
public void display(){//总输出
displayStudents();
displayCourses();
displayClasses();
}
public ArrayList<ChooseCourse> getStudentSelects(String id){
ArrayList<ChooseCourse> choose=new ArrayList<>();
for(ChooseCourse cc:listChooseCourse) {
if (cc.student.getId().equals(id))
choose.add(cc);
}
return choose;
}
public ArrayList<ChooseCourse> getCourseSelects(String courseName){
ArrayList<ChooseCourse> choose=new ArrayList<>();
for(ChooseCourse cc:listChooseCourse) {
if (cc.course.getCourseName().equals(courseName))
choose.add(cc);
}
return choose;
}
public ArrayList<ChooseCourse> getClassSelects(String clsId){
ArrayList<ChooseCourse> chooseCourse =new ArrayList<>();
for(ChooseCourse cc:listChooseCourse) {
if (cc.student.getClsId().equals(clsId))
chooseCourse.add(cc);
}
return chooseCourse;
}
public int getAvgSumScore(ArrayList<ChooseCourse> cs){
int sum=0;
for(ChooseCourse c:cs){
sum+=c.grade.getSumGrade();
}
return (int)sum/cs.size();
}
public int getAvgPinshiScore(ArrayList<ChooseCourse> cs){
int sum=0;
for(ChooseCourse c : cs){
sum+=c.grade.getpinshi();
}
return (int)sum/cs.size();
}
public int getAvgExamScore(ArrayList<ChooseCourse> cs){
int sum=0;
for(ChooseCourse c:cs){
sum+=c.grade.exam;
}
return (int)sum/cs.size();
}
}
class ChooseCourse{
Course course;
Student student;
Grade grade;
public ChooseCourse(Course course,Student student,Grade grade) {
this.course = course;
this.student=student;
this.grade=grade;
}
}
class Student implements Comparable<Student>{
String stuName;
String id;
String clsId;
public String getId(){
return id;
}
public String getStuName(){
return stuName;
}
public String getClsId(){
return clsId;
}
public Student(String clsId,String id,String stuName) {
this.clsId=clsId;
this.id=id;
this.stuName=stuName;
}
public int compareTo(Student stu){
return getId().compareTo(stu.getId());
}
}
class Course implements Comparable<Course>{
String courseName;
String type;//必修选修
String testType;//考试考察
public Course() {
}
public Course(String courseName,String type,String testType) {
this.courseName=courseName;
this.type=type;
this.testType=testType;
}
public String getCourseName(){
return courseName;
}
public String getType(){
return type;
}
public String getTestType(){
return testType;
}
@Override
public int compareTo(Course o) {
Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
return compare.compare(courseName,o.getCourseName());
}
}
class Class implements Comparable<Class>{
String classId;//班级号
public Class() {
}
public String getClassId(){
return classId;
}
public Class(String classId) {
this.classId = classId;
}
@Override
public int compareTo(Class o) {
return getClassId().compareTo(o.getClassId());
}
}
abstract class Grade{
int exam;
public Grade() {
}
public abstract int getpinshi();
public abstract int getSumGrade();
}
class ExamGrade extends Grade{
int pinshi;
public ExamGrade(int pinshi,int exam) {
this.pinshi=pinshi;
this.exam=exam;
}
public int getpinshi(){
return pinshi;
}
public int getexam(){
return 0;
}
public int getSumGrade(){
return (int)(pinshi*0.3+exam*0.7);
}
}
class AssessGrade extends Grade{
public AssessGrade(int exam) {
this.exam=exam;
}
public int getexam(){
return exam;
}
@Override
public int getpinshi() {
return 0;
}
public int getSumGrade(){
return exam;
}
}
生成类图:

我的思路:
此题比较难,应该是题集里面最难的一道题。这题我也没有全对,只对了大部分。这题也是看了提示,主方法是非常简洁的,只有几行代码,一行用来读取,一行用来处理,一行用来输入,然后就结束。处理输出写了一个Input类,里面写了检测信息是否正确的方法,还有信息处理方法,信息处理就是要把每一条信息里面的信息全部分开读取,之后再用成绩类处理学生成绩,最后输出信息,但是输出信息也是要分情况输出。大致思路就是这样,十分繁琐,还需要细节处理,例如排序时要重写compara方法,储存信息用链表等,都是这道题目得分点。
运行结果:

OOP11-7-2
输入多个学生的成绩信息,包括:学号、姓名、成绩。
学号是每个学生的唯一识别号,互不相同。
姓名可能会存在重复。
要求:使用HashMap存储学生信息。
输入格式:
输入多个学生的成绩信息,每个学生的成绩信息格式:学号+英文空格+姓名+英文空格+成绩
以“end”为输入结束标志
输出格式:
按学号从大到小的顺序输出所有学生信息,每个学生信息的输出格式:学号+英文空格+姓名+英文空格+成绩
输入样例:
在这里给出一组输入。例如:
20201124 张少军 83
20201136 李四 78
20201118 郑觉先 80
end
输出样例:
在这里给出相应的输出。例如:
20201136 李四 78
20201124 张少军 83
20201118 郑觉先 80
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
源码:
点击查看代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
HashMap<String, String[]> map = new HashMap<>();
String line = sc.nextLine();
while(!line.equals("end")){
String[] stuMessage = line.split(" ");
String[] message = {stuMessage[1],stuMessage[2]};
map.put(stuMessage[0],message);
line = sc.nextLine();
}
TreeMap<String,String[]>sortedMap = new TreeMap<>(Collections.reverseOrder());
sortedMap.putAll(map);
for (Map.Entry<String,String[]>entry:sortedMap.entrySet()
) {
String key = entry.getKey();
String[] value = entry.getValue();
System.out.println(key + " " + value[0] + " " + value[1]);
}
}
}
生成类图:

我的思路:
这题就是一个哈希树的排序,都是哈希树不能直接排序,使用TreeMap进行排序,创建一个反序列的TreeMap,将哈希树全部放进TreeMap里面,就可以直接获得结果了。
运行结果:

三、踩坑心得
这次作业难度升级也暴露出了我的很多问题,都是我踩的坑,就比如那个读取输入,我一开始并没有在意next()和nextLine()的区别,导致我在最开始读取输入时老是出错,后面查阅资料才发现next()只读取后面一个字符串,而nextLine()是读取一行,但是我在使用nextLine()读取一行信息时有时会读到空,但是输入里面有字符串,后面才知道原来出现这种情况时要在nextLine()前面再加一个nextLine(),后面的这个输入就是用来消除空格的,之后才可以正常读取信息;同样的,scanner.hasNextLine()也是经常读不了,使用它用于循环停止总是错误,就是因为它读取了回车,要使它能够正常用于停止循环只能使再写一个nextLine()用来判断输入是否为空,这应该就是我这次最大的收获了。还有就是哈希树,它其实不难,就是会忘记里面的方法,我只有在看着注解的情况下才能使用好它,特别是里面的值对,经常用错,这是我应该继续去攻克的地方。
四、改进建议
改进建议的话,我感觉前面也提的差不多了,我还需要写更多的代码,提高写代码的速度,增加对各种方法的熟练度,以及提高对于复杂问题的分解的能力,就像前面提到的课程设计题目,我的大致思路是正确的,但是最后却没有全部正确,就是因为对复杂繁琐问题的分解能力不够,才导致我到后面处理细节问题出现问题,考虑不周;同时也需要提高处理细节的能力。
五、总结
这次大作业难度大,收获也多。仔细钻研了之前没有认真对待过的问题:next()和nextLine()的区别,又使用了正则表达式,现在又比之前更加熟练。现在对题目给类图的的题目有了更加深刻的理解,并且可以相对轻松的把题目写对,对与需要自己设计类的题目还差点意思。不过我先对于过去,觉得自己的代码能力已经迈了一大步了,以后也要继续往前走。在以后学习过程中我需要多动手,尽量把老师上课讲过的代码自己再写一遍,最好做到不看笔记写,把这些东西全部装脑子里面,这样的话,应该会提高进步的速度。
评价:
我是相对来说比较肯定老师的教学方法的,边讲边练的教学模式我觉得非常适合我们这些小白,小白就是需要大量的练习才可以进步,前期是非常需要大量的练习的,特别是老师刚刚讲完就立马练习,这样效率高。对于线上线下混合式教学,我觉得仁者见仁智者见智,主要靠自觉性,对于线上的课程,自觉的学生应该是会比普通学生有更加扎实的基本功,相对的,不自觉的学生就差点。对于PTA我觉得应该出分类题目,而不是以题集的形式出现,题集更多的是一个综合能力,要是能多一些基础题就还行,这些基础题也没有人讲,老师都是默认的,这样的话基础不会太牢固。最后,我还是希望老师上课能多讲讲,多一些内容,高一些效率,我认为老师讲课的作用除了引导学生正确学习,还可以提高学生的学习效率,难点的东西,老师讲一遍自己在理解一遍能比自己单独琢磨有效率的多。