第一次博客作业
目录
1.前言
一、知识点
关于类
1:类似于C语言的结构体,但比C语言中的结构体作用更多,且适用范围更广
2:懂得封装和公开的区别,即private和public的区别,用private可以防止数据的泄露
3:用类把题目分解,以便更好的解决题目,创立多个类,来分解题目。
4:在Java开发中,类是实现功能的基础。通过定义类,我们可以组织和管理代码,实现各种复杂的功能和逻辑。
5:此外,类还可以作为数据类型使用,用于创建和操作对象。因此,掌握Java中的类及其相关特性,对于编写高质量、可维护的Java代码至关重要。
关于列表
1:ArrayList:基于动态数组实现,查询效率高,但插入和删除操作可能会涉及元素的移动,效率相对较低
2:使用列表能更好的存储题目数据,且能更好的访问其中的元素
3:懂得这些函数的用法add()remove()......
关于哈希表
1:哈希表通过哈希函数将键(Key)映射到存储桶(Bucket)中,从而实现对数据的快速查找。
2:使用哈希表能简便代码,更好的解题。
3:懂得这些函数put(K key, V value)get(Object key)remove(Object key)....用法
二、作业
第一次题目集:主要考察正则表达式、字符串排序、继承以及多态、接口以及多态。题量较多,正则表达式有三道题目,其他知识点都是一道。难度适中,继承和多态、接口与多态并不复杂,正则表达式的题目较为简单。
第二次题目集:主要考察正则表达式、聚合、继承的实现。题量较少,每个知识点只有一道题目。难度较大,其中正则表达式的题目需要花费大量时间来解决。
第三次题目集:主要考察聚合、正则表达式、map的运用、字符串语法、排序。题量适中,每个知识点只有一道题目。难度适中,经过上次题目的练习,写这几道题目的思路清晰了不少,但在统计java程序中关键词出现次数的题目中,需要使用map类和正则表达式中的Pattern类和Matcher类,花费了较多时间。
2.第一次大作业
7-1 答题判题程序-1
分数 50
作者 蔡轲
单位 南昌航空大学
设计实现答题程序,模拟一个小型的测试,要求输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分三部分:
1、题目数量
格式:整数数值,若超过1位最高位不能为0,
样例:34
2、题目内容
一行为一道题,可以输入多行数据。
格式:"#N:"+题号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式约束:题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
3、答题信息
答题信息按行输入,每一行为一组答案,每组答案包含第2部分所有题目的解题答案,答案的顺序号与题目题号相对应。
格式:"#A:"+答案内容
格式约束:答案数量与第2部分题目的数量相同,答案之间以英文空格分隔。
样例:#A:2 #A:78
2是题号为1的题目的答案
78是题号为2的题目的答案
答题信息以一行"end"标记结束,"end"之后的信息忽略。
输出格式:
1、题目数量
格式:整数数值,若超过1位最高位不能为0,
样例:34
2、答题信息
一行为一道题的答题信息,根据题目的数量输出多行数据。
格式:题目内容+" ~"+答案
样例:1+1=~2
2+2= ~4
3、判题信息
判题信息为一行数据,一条答题记录每个答案的判断结果,答案的先后顺序与题目题号相对应。
格式:判题结果+" "+判题结果
格式约束:
1、判题结果输出只能是true或者false,
2、判题信息的顺序与输入答题信息中的顺序相同
样例:true false true
输入样例1:
单个题目。例如:
1
#N:1 #Q:1+1= #A:2
#A:2
end
输出样例1:
在这里给出相应的输出。例如:
1+1=~2
true
输入样例2:
单个题目。例如:
1
#N:1 #Q:1+1= #A:2
#A:4
end
输出样例2:
在这里给出相应的输出。例如:
1+1=~4
false
输入样例3:
多个题目。例如:
2
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#A:2 #A:4
end
输出样例3:
在这里给出相应的输出。例如:
1+1=~2
2+2=~4
true true
输入样例4:
多个题目。例如:
2
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#A:2 #A:2
end
输出样例4:
在这里给出相应的输出。例如:
1+1=~2
2+2=~2
true false
输入样例5:
多个题目,题号顺序与输入顺序不同。例如:
2
#N:2 #Q:1+1= #A:2
#N:1 #Q:5+5= #A:10
#A:10 #A:2
end
输出样例5:
在这里给出相应的输出。例如:
5+5=~10
1+1=~2
true true
输入样例6:
含多余的空格符。例如:
1
#N:1 #Q: The starting point of the Long March is #A:ruijin
#A:ruijin
end
输出样例6:
在这里给出相应的输出。例如:
The starting point of the Long March is~ruijin
true
输入样例7:
含多余的空格符。例如:
1
#N: 1 #Q: 5 +5= #A:10
#A:10
end
输出样例7:
在这里给出相应的输出。例如:
5 +5=~10
true
设计建议:
以下是针对以上题目要求的设计建议,其中的属性、方法为最小集,实现代码中可根据情况添加所需的内容:
题目类(用于封装单个题目的信息):
属性:题目编号、题目内容、标准答案-standardAnswer
方法:数据读写set\get方法、
判题方法(答案-answer):判断答案-answer是否符合标准答案-standardAnswer
试卷类(用于封装整套题目的信息)
属性:题目列表(题目类的对象集合)、题目数量
方法:判题方法(题号-num、答案-answer):判断答案-answer是否符合对应题号的题目标准答案-standardAnswer
保存题目(题号-num、题目-question):将题目保存到题目列表中,保存位置与num要能对应
答卷类(用于封装答题信息)
属性:试卷(试卷类的对象)、答案列表(保存每一题的答案)、判题列表(保存每一题的判题结果true/false)
方法:判题方法(题号-num):判断答案列表中第num题的结果是否符合试卷中对应题号的题目标准答案
输出方法(题号-num):按照题目的格式要求,输出题号为num的题目的内容和答题结果。
保存一个答案(题号-num,答案-answer):保存题号为num的题目的答题结果answer。
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question {
private int number;
private String question;
private String answer;
public Question() {
}
public Question(int number, String question, String answer) {
this.number = number;
this.question = question;
this.answer = answer;
}
public int getnumber()
{
return number;
}
public String getanswer(){
return this.answer;
}
public String getq(){
return this.question;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
scanner.nextLine();
String regex="#A:|#N:|#Q:";
Question []ques=new Question[a];
for (int i = 0; i < a; i++) {
String input = scanner.nextLine();
String []arr=input.split(regex);
ques[i]=new Question(Integer.parseInt(arr[1].trim()),arr[2].trim(),arr[3].trim());
}
String []an=new String[a];
int l=0;
while(true){
String str=scanner.next();
if(str.equals("end")){
break;
}
an[l]=str.replaceAll("#A:","");
l++;
}
boolean []arrboolean=new boolean[a];
for(int i=0;i<a-1;i++)
{
for(int j=0;j<a-1-i;j++)
{
if(ques[i].getnumber()>ques[i+1].getnumber())
{
Question temp=ques[i];
ques[i]=ques[i+1];
ques[i+1]=temp;
}
}
}
for(int i=0;i<l;i++){
if(ques[i].getanswer().equals(an[i]))
{
arrboolean[i]=true;
}
else{
arrboolean[i]=false;
}
}
for(int i=0;i<l;i++){
System.out.println(ques[i].getq()+"~"+an[i]);
}
for(int i=0;i<l;i++){
System.out.print(arrboolean[i]);
if(i!=l-1){
System.out.print(" ");
}
}
}
}

第一次大作业设计与分析:第一次大作业难度还行,用了正则表达式提取数据,之前没学过正则表达式,所以对我们来说比较新奇,所以一开始无从下手,让我不知所措,后面听了正则表达式,突然恍然大悟,知道怎么用正则表达式提取数据,提取数据之后设计三个类,一个题目类,一个试卷类,一个答卷类,在用个for循环就可以写出来。
采坑心得:对于字符串的比较,不要使用 == 运算符,而应使用 equals 方法。
数据库操作中,要注意处理异常情况,防止数据丢失或错误。
对于复杂的逻辑,要注意代码的可读性和可维护性,以便后续的修改和扩展。
改进建议:多用列表存储,可以不转数组,列表中有很多函数,可以减少循环,简化代码
3.第二次大作业
7-2 答题判题程序-2
分数 54
作者 蔡轲
单位 南昌航空大学
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-1基础上增补或者修改的内容。
要求输入题目信息、试卷信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分三种,三种信息可能会打乱顺序混合输入:
1、题目信息
一行为一道题,可输入多行数据(多道题)。
格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式约束:
1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、试卷信息
一行为一张试卷,可输入多行数据(多张卷)。
格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值
题目编号应与题目信息中的编号对应。
一行信息中可有多项题目编号与分值。
样例:#T:1 3-5 4-8 5-2
3、答卷信息
答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序与试卷信息中的题目顺序相对应。
格式:"#S:"+试卷号+" "+"#A:"+答案内容
格式约束:答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
样例:#S:1 #A:5 #A:22
1是试卷号
5是1号试卷的顺序第1题的题目答案
22是1号试卷的顺序第2题的题目答案
答题信息以一行"end"标记结束,"end"之后的信息忽略。
输出格式:
1、试卷总分警示
该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100分,该部分忽略,不输出。
格式:"alert: full score of test paper"+试卷号+" is not 100 points"
样例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。
格式:题目内容+"~"+答案++"~"+判题结果(true/false)
约束:如果输入的答案信息少于试卷的题目数量,答案的题目要输"answer is null"
样例:3+2=~5~true
4+6=~22~false.
answer is null
3、判分信息
判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
格式:题目得分+" "+....+题目得分+"~"+总分
格式约束:
1、没有输入答案的题目计0分
2、判题信息的顺序与输入答题信息中的顺序相同
样例:5 8 0~13
根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
4、提示错误的试卷号
如果答案信息中试卷的编号找不到,则输出”the test paper number does not exist”,参见样例9。
设计建议:
参考答题判题程序-1,建议增加答题类,类的内容以及类之间的关联自行设计。
输入样例1:
一张试卷一张答卷。试卷满分不等于100。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#S:1 #A:5 #A:22
end
输出样例1:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
2+2=~22~false
0 0~0
输入样例2:
一张试卷一张答卷。试卷满分不等于100。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-70 2-30
#S:1 #A:5 #A:22
end
输出样例2:
在这里给出相应的输出。例如:
1+1=~5~false
2+2=~22~false
0 0~0
输入样例3:
一张试卷、一张答卷。各类信息混合输入。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-70 2-30
#N:3 #Q:3+2= #A:5
#S:1 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
1+1=~5~false
2+2=~4~true
0 30~30
输入样例4:
试卷题目的顺序与题号不一致。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 2-70 1-30
#N:3 #Q:3+2= #A:5
#S:1 #A:5 #A:22
end
输出样例:
在这里给出相应的输出。例如:
2+2=~5~false
1+1=~22~false
0 0~0
输入样例5:
乱序输入。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-70 2-30
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
end
输出样例:
在这里给出相应的输出。例如:
3+2=~5~true
2+2=~22~false
70 0~70
输入样例6:
乱序输入+两份答卷。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-70 2-30
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#S:1 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
3+2=~5~true
2+2=~22~false
70 0~70
3+2=~5~true
2+2=~4~true
70 30~100
输入样例7:
乱序输入+分值不足100+两份答卷。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#S:1 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
3+2=~5~true
2+2=~22~false
7 0~7
3+2=~5~true
2+2=~4~true
7 6~13
输入样例8:
乱序输入+分值不足100+两份答卷+答卷缺失部分答案。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#T:2 2-5 1-3 3-2
#S:2 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
3+2=~5~true
2+2=~22~false
7 0~7
2+2=~5~false
1+1=~4~false
answer is null
0 0 0~0
输入样例9:
乱序输入+分值不足100+两份答卷+无效的试卷号。例如:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:3 #A:5 #A:4
end
输出样例:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
The test paper number does not exist
import java.util.*;
public class Main {
public static void main(String[] args) {
ProblemBank problemBank = new ProblemBank();
LinkedList<Paper> papers = new LinkedList<Paper>();
LinkedList<Answer> answers = new LinkedList<Answer>();
String[] strsT = new String[100];
String[] strs;
String[] strs1;
int count1 = 0;
Scanner in = new Scanner(System.in);
in.useDelimiter("\n");
String str = in.next();
int number = 0;
//输入阶段
while (!str.equals("end")) {
if (str.charAt(1) == 'N') {//题目输入
strs = str.split(" *#A: *| *#Q: *| *#N: *");
Problem problem = new Problem();
problem.setNumber(Integer.parseInt(strs[1]));
problem.setName(strs[2]);
problem.setAnswer(strs[3]);
problemBank.setProblems(problem);
str = in.next();
number++;
}
if (str.charAt(1) == 'T') {//分值、试卷输入
count1++;
strsT[count1] = str;
str = in.next();
}
if (str.charAt(1) == 'S') {//答案输入
Answer answer = new Answer();
strs = str.split(" *#S: *| *#A: *");
answer.setNumber(Integer.parseInt(strs[1]));
for(int i = 2;i < strs.length;i++){
answer.setAnswer(strs[i]);
}
answer.setCount(strs.length - 2);
answers.add(answer);
str = in.next();
}
}
//试卷组卷
for(int i = 1;i <= count1;i++){
strs = strsT[i].split( " *#T: *|[\\s+]");
Paper paper =new Paper();
paper.setNumber(Integer.parseInt(strs[1]));
for (int k = 2; k < strs.length; k++) {
strs1 = strs[k].split("-");
paper.setPoints(Integer.parseInt(strs1[0]), Integer.parseInt(strs1[1]));
paper.setTest(problemBank.getProblems()[Integer.parseInt(strs1[0])]);
}
paper.setCount(strs.length - 2);
papers.add(paper);
}
//输出
View view = new View();
for(int i = 0;i < papers.size();i++){
view.showPoints(papers.get(i));
}
view.showResults(papers,answers,number,problemBank);
}
}
class Paper {
private int number;//试卷号
private int[] points = new int[100];//各题的分数
private int count = 0;
Problem[] test = new Problem[100];//题目
public Paper() {
Arrays.fill(points, -1);
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public int[] getPoints() {
return points;
}
public void setPoints(int x, int point) {
points[count+1] = point;
}
public Problem[] getTest() {
return test;
}
public void setTest(Problem problem) {
count++;
test[count] = problem;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
class AnswerPaper {
private int number;//题目个数
private Paper paper = new Paper();//试卷
private ProblemBank problemBank;//题库
private Answer answer = new Answer();
private boolean[] answerRight = new boolean[100];
public AnswerPaper(int number, ProblemBank problemBank, Paper paper, Answer answer) {
this.number = number;
this.paper = paper;
this.problemBank = problemBank;
this.answer = answer;
}
public AnswerPaper() {
}
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public void setAnswer(Answer answer) {
this.answer = answer;
}
public Answer getAnswer() {
return answer;
}
public int addPoints() {
int sum = 0;
for (int i = 1; i <= paper.getCount(); i++) {
if (answerRight[i]) {
sum += paper.getPoints()[i];
}
}
return sum;
}
public boolean[] checkAnswer() {
for (int i = 1; i <= paper.getCount(); i++) {
if (paper.getTest()[i].isRight(answer.getAnswer()[i])) {
answerRight[i] = true;
} else {
answerRight[i] = false;
}
}
return answerRight;
}
public void showResult() {
for (int i = 1; i <= paper.getCount(); i++) {
if(i <= answer.getCount()){
if (answerRight[i]) {
System.out.println(paper.getTest()[i].getName() + "~" + answer.getAnswer()[i] + "~" + true);
} else {
System.out.println(paper.getTest()[i].getName() + "~" + answer.getAnswer()[i] + "~" + false);
}
}else{
System.out.println("answer is null");
}
}
for (int i = 1; i <= paper.getCount(); i++) {
if (answerRight[i]) {
System.out.print(paper.getPoints()[i]);
} else {
System.out.print(0);
}
if (i != paper.getCount()) {
System.out.print(" ");
}
}
System.out.println("~" + addPoints());
}
}
class View {
public void showPoints(Paper paper){
int sum = 0;
for (int i = 1; i <= paper.getCount(); i++) {
if(paper.getPoints()[i] != -1){
sum += paper.getPoints()[i];
}
}
if (sum != 100) {
System.out.println("alert: full score of test paper" + paper.getNumber() + " is not 100 points");
}
}
public void showResults(LinkedList<Paper> papers,LinkedList<Answer> answers,int number,ProblemBank problemBank) {
for (int i = 0; i < answers.size(); i++) {
int count = 0;
for (int j = 0; j < papers.size(); j++) {
if (answers.get(i).getNumber() == papers.get(j).getNumber()) {
count++;
}
}
if (count == 0) {
System.out.println("The test paper number does not exist");
} else {
AnswerPaper answerPaper = new AnswerPaper(number, problemBank, papers.get(answers.get(i).getNumber() - 1), answers.get(i));
boolean[] answerRight = answerPaper.checkAnswer();
answerPaper.showResult();
}
}
}
}
class Answer {
private int number = 0;//答案号
private String[] answer = new String[100];//答案
private int count = 0;
public void Answer(){
}
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public void setAnswer(String answer) {
count++;
this.answer[count] = answer;
}
public String[] getAnswer() {
return answer;
}
public void setCount(int count) {
this.count = count;
}
public int getCount() {
return count;
}
}
class Problem {
private int number;//题目号
private String name;//题目内容
private String answer;//标准答案
public Problem() {
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public boolean isRight(String answer1) {
if (answer.equals(answer1)) {
return true;
} else {
return false;
}
}
}
class ProblemBank {
private int number;//题目数量
private Problem[] problems = new Problem[100];//题库
public ProblemBank() {
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public void setProblems(Problem problem) {
problems[problem.getNumber()] = problem;
}
public Problem[] getProblems() {
return problems;
}
}

第二次大作业设计与分析:相比较第一次大作业,第二次大作业难度提升较大,它没有告诉我们有几个题目,还有那个分数判断也比较难,所以我们先要用正则表达式提取数据,然后要用动态数组储存数据,一开始没有动态数组根本不会写,因为它的题目顺序也打乱啦,学了动态数组之后,问题一下子就解决啦,这次我们要设计四个类,一个题目类,一个试卷类,一个答卷类,一个分数类,在用多个for循环就可以写出来了。
采坑心得:对于字符串的比较,不要使用 == 运算符,而应使用 equals 方法。
数据库操作中,要注意处理异常情况,防止数据丢失或错误。
对于复杂的逻辑,要注意代码的可读性和可维护性,以便后续的修改和扩展。
避免在循环中创建新对象,可能会导致性能下降。
改进建议:使用哈希表,能减少循环的嵌套,且哈希表能迅速获取题目数据。
4.第三次大作业
7-3 答题判题程序-3
分数 80
作者 蔡轲
单位 南昌航空大学
设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-2基础上增补或者修改的内容,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。
输入格式:
程序输入信息分五种,信息可能会打乱顺序混合输入。
1、题目信息
题目信息为独行输入,一行为一道题,多道题可分多行输入。
格式:"#N:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案
格式约束:
1、题目的输入顺序与题号不相关,不一定按题号顺序从小到大输入。
2、允许题目编号有缺失,例如:所有输入的题号为1、2、5,缺少其中的3号题。此种情况视为正常。
样例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
2、试卷信息
试卷信息为独行输入,一行为一张试卷,多张卷可分多行输入数据。
格式:"#T:"+试卷号+" "+题目编号+"-"+题目分值+" "+题目编号+"-"+题目分值+...
格式约束:
题目编号应与题目信息中的编号对应。
一行信息中可有多项题目编号与分值。
样例:#T:1 3-5 4-8 5-2
3、学生信息
学生信息只输入一行,一行中包括所有学生的信息,每个学生的信息包括学号和姓名,格式如下。
格式:"#X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名
格式约束:
答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
样例:
#S:1 #A:5 #A:22
1是试卷号
5是1号试卷的顺序第1题的题目答案
4、答卷信息
答卷信息按行输入,每一行为一张答卷的答案,每组答案包含某个试卷信息中的题目的解题答案,答案的顺序号与试 卷信息中的题目顺序相对应。答卷中:
格式:"#S:"+试卷号+" "+学号+" "+"#A:"+试卷题目的顺序号+"-"+答案内容+...
格式约束:
答案数量可以不等于试卷信息中题目的数量,没有答案的题目计0分,多余的答案直接忽略,答案之间以英文空格分隔。
答案内容可以为空,即””。
答案内容中如果首尾有多余的空格,应去除后再进行判断。
样例:
#T:1 1-5 3-2 2-5 6-9 4-10 7-3
#S:1 20201103 #A:2-5 #A:6-4
1是试卷号
20201103是学号
2-5中的2是试卷中顺序号,5是试卷第2题的答案,即T中3-2的答案
6-4中的6是试卷中顺序号,4是试卷第6题的答案,即T中7-3的答案
注意:不要混淆顺序号与题号
5、删除题目信息
删除题目信息为独行输入,每一行为一条删除信息,多条删除信息可分多行输入。该信息用于删除一道题目信息,题目被删除之后,引用该题目的试卷依然有效,但被删除的题目将以0分计,同时在输出答案时,题目内容与答案改为一条失效提示,例如:”the question 2 invalid~0”
格式:"#D:N-"+题目号
格式约束:
题目号与第一项”题目信息”中的题号相对应,不是试卷中的题目顺序号。
本题暂不考虑删除的题号不存在的情况。
样例:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
输出
alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
答题信息以一行"end"标记结束,"end"之后的信息忽略。
输出格式:
1、试卷总分警示
该部分仅当一张试卷的总分分值不等于100分时作提示之用,试卷依然属于正常试卷,可用于后面的答题。如果总分等于100 分,该部分忽略,不输出。
格式:"alert: full score of test paper"+试卷号+" is not 100 points"
样例:alert: full score of test paper2 is not 100 points
2、答卷信息
一行为一道题的答题信息,根据试卷的题目的数量输出多行数据。
格式:题目内容+"~"+答案++"~"+判题结果(true/false)
约束:如果输入的答案信息少于试卷的题目数量,每一个缺失答案的题目都要输出"answer is null" 。
样例:
3+2=~5~true
4+6=~22~false.
answer is null
3、判分信息
判分信息为一行数据,是一条答题记录所对应试卷的每道小题的计分以及总分,计分输出的先后顺序与题目题号相对应。
格式:**学号+" "+姓名+": "**+题目得分+" "+....+题目得分+"~"+总分
格式约束:
1、没有输入答案的题目、被删除的题目、答案错误的题目计0分
2、判题信息的顺序与输入答题信息中的顺序相同
样例:20201103 Tom: 0 0~0
根据输入的答卷的数量以上2、3项答卷信息与判分信息将重复输出。
4、被删除的题目提示信息
当某题目被试卷引用,同时被删除时,答案中输出提示信息。样例见第5种输入信息“删除题目信息”。
5、题目引用错误提示信息
试卷错误地引用了一道不存在题号的试题,在输出学生答案时,提示”non-existent question~”加答案。例如:
输入:
#N:1 #Q:1+1= #A:2
#T:1 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-4
end
输出:
alert: full score of test paper1 is not 100 points
non-existent question~0
20201103 Tom: 0~0
如果答案输出时,一道题目同时出现答案不存在、引用错误题号、题目被删除,只提示一种信息,答案不存在的优先级最高,例如:
输入:
#N:1 #Q:1+1= #A:2
#T:1 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103
end
输出:
alert: full score of test paper1 is not 100 points
answer is null
20201103 Tom: 0~0
6、格式错误提示信息
输入信息只要不符合格式要求,均输出”wrong format:”+信息内容。
例如:wrong format:2 #Q:2+2= #4
7、试卷号引用错误提示输出
如果答卷信息中试卷的编号找不到,则输出”the test paper number does not exist”,答卷中的答案不用输出,参见样例8。
8、学号引用错误提示信息
如果答卷中的学号信息不在学生列表中,答案照常输出,判分时提示错误。参见样例9。
本题暂不考虑出现多张答卷的信息的情况。
输入样例1:
简单输入,不含删除题目信息。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:1 20201103 #A:1-5
end
输出样例1:
在这里给出相应的输出。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
20201103 Tom: 0~0
输入样例2:
简单输入,答卷中含多余题目信息(忽略不计)。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:1 20201103 #A:1-2 #A:2-3
end
输出样例3
简单测试,含删除题目信息。例如:
alert: full score of test paper1 is not 100 points
1+1=~2~true
20201103 Tom: 5~5
输入样例3:
简单测试,含删除题目信息。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
输出样例3:
在这里给出相应的输出,第二题由于被删除,输出题目失效提示。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
输入样例4:
简单测试,含试卷无效题目的引用信息以及删除题目信息(由于题目本身无效,忽略)。例如:
#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 3-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
输出样例4:
输出不存在的题目提示信息。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
non-existent question~0
20201103 Tom: 0 0~0
输入样例5:
综合测试,含错误格式输入、有效删除以及无效题目引用信息。例如:
#N:1 +1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5 #A:2-4
#D:N-2
end
输出样例5:
在这里给出相应的输出。例如:
wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
the question 2 invalid~0
20201103 Tom: 0 0~0
输入样例6:
综合测试,含错误格式输入、有效删除、无效题目引用信息以及答案没有输入的情况。例如:
#N:1 +1= #A:2
#N:2 #Q:2+2= #A:4
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:1-5
#D:N-2
end
输出样例6:
答案没有输入的优先级最高。例如:
wrong format:#N:1 +1= #A:2
alert: full score of test paper1 is not 100 points
non-existent question~0
answer is null
20201103 Tom: 0 0~0
输入样例7:
综合测试,正常输入,含删除信息。例如:
#N:2 #Q:2+2= #A:4
#N:1 #Q:1+1= #A:2
#T:1 1-5 2-8
#X:20201103 Tom-20201104 Jack-20201105 Www
#S:1 20201103 #A:2-4 #A:1-5
#D:N-2
end
输出样例7:
例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
the question 2 invalid~0
20201103 Tom: 0 0~0
输入样例8:
综合测试,无效的试卷引用。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201103 Tom
#S:2 20201103 #A:1-5 #A:2-4
end
输出样例8:
例如:
alert: full score of test paper1 is not 100 points
The test paper number does not exist
输入样例9:
无效的学号引用。例如:
#N:1 #Q:1+1= #A:2
#T:1 1-5
#X:20201106 Tom
#S:1 20201103 #A:1-5 #A:2-4
end
输出样例9:
答案照常输出,判分时提示错误。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
20201103 not found
输入样例10:
信息可打乱顺序输入:序号不是按大小排列,各类信息交错输入。但本题不考虑引用的题目在被引用的信息之后出现的情况(如试卷引用的所有题目应该在试卷信息之前输入),所有引用的数据应该在被引用的信息之前给出。例如:
#N:3 #Q:中国第一颗原子弹的爆炸时间 #A:1964.10.16
#N:1 #Q:1+1= #A:2
#X:20201103 Tom-20201104 Jack-20201105 Www
#T:1 1-5 3-8
#N:2 #Q:2+2= #A:4
#S:1 20201103 #A:1-5 #A:2-4
end
输出样例10:
答案按试卷中的题目顺序输出。例如:
alert: full score of test paper1 is not 100 points
1+1=~5~false
中国第一颗原子弹的爆炸时间~4~false
20201103 Tom: 0 0~0
import javax.swing.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import java.util.Comparator;
class Issue//题目类
{
public int number;
public String question;
public String answer;//标准答案
public Issue(int number, String question, String answer)
{
this.number = number;
this.question = question;
this.answer = answer;
}
public Issue()
{
}
public Boolean check(String answer)
{
if(this.answer.equals(answer))
{
return true;
}
else
{
return false;
}
}
public String toString(String answer)
{
if(this.answer.equals(answer))
{
return this.question+"~"+answer+"~true";
}
else
{
return this.question+"~"+answer+"~false";
}
}
}
class Question
{
int number;//题目序号
int score;//题目分值
public Question(int number, int score)
{
this.number = number;
this.score = score;
}
}
class ExamPaper//试卷类
{
public int examnumber;//试卷号
public List<Question> questions;
public ExamPaper(int examnumber)
{
this.examnumber = examnumber;
this.questions = new ArrayList<>();
}
public void addQuestion(Question question)
{
questions.add(question);
}
public String toString()
{
int sum=0;
for (Question question:this.questions)
{
sum=sum+question.score;
}
if(sum!=100)
{
return "alert: full score of test paper"+this.examnumber+" is not 100 points";
}
else
{
return " ";
}
}
}
class AnswerPaper//答卷类
{
public int papernumber;
public String num;//学号
public HashMap<Integer,String> answers;//试卷序号和题目答案
public AnswerPaper(int papernumber,String num)
{
this.papernumber = papernumber;
this.num=num;
this.answers = new HashMap<Integer,String>();
}
public void addAnswer(int number,String answer)
{
answers.put(number,answer);
}
}
class Student
{
public String num;//学号
public String name;//姓名
public Student(String num,String name)
{
this.num=num;
this.name=name;
}
}
public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
HashMap<Integer,Issue> Issues= new HashMap<Integer, Issue>();//题目类哈希表
HashMap<Integer,ExamPaper> ExamPapers= new HashMap<Integer, ExamPaper>();//试卷类哈希表
List<AnswerPaper> AnswerPapers = new ArrayList<>();//答卷类列表
HashMap<String,Student> Students= new HashMap<String,Student>();//学生类哈希表
List<Integer> del = new ArrayList<>();//删除题目列表
List<String> wrong = new ArrayList<>();//错误格式列表
while (true)
{
String line = input.nextLine();
if (line.equalsIgnoreCase("end"))
{
break;
}
if (line.startsWith("#N:"))//存储题目类
{
Pattern pattern = Pattern.compile("#N:(\\d+) #Q:(.+) #A:");
Pattern pattern1 = Pattern.compile("#A:(.+)");
Matcher matcher = pattern.matcher(line);
Matcher matcher1 = pattern1.matcher(line);
Issue issue = new Issue();;
if(matcher.find())
{
issue.number = Integer.parseInt(matcher.group(1));
issue.question = matcher.group(2);
if(matcher1.find())
{
issue.answer = matcher1.group(1);
}
else
{
issue.answer="";
}
Issues.put(issue.number,issue);
issue = null;
}
else
{
wrong.add("wrong format:"+line);
}
}
else if (line.startsWith("#T:"))//试卷类
{
Question a = null;
ExamPaper a1 = null;
Pattern p = Pattern.compile("#T:(\\d) (\\d+)-");//试卷编号
Matcher m = p.matcher(line);
if(m.find())
{
Pattern p1 = Pattern.compile("#T:(\\d+)");//试卷编号
Matcher m1 = p1.matcher(line);
if (m1.find())
{
a1 = new ExamPaper(Integer.parseInt(m1.group(1)));
line = line.replaceFirst("#T:\\d+\\s+", "");
Pattern p2 = Pattern.compile("(\\d+)-(\\d+)");//获取题目序号和分值
Matcher m2 = p2.matcher(line);
while (m2.find())
{
a = new Question(Integer.parseInt(m2.group(1)), Integer.parseInt(m2.group(2)));
a1.addQuestion(a);
a = null;
}
ExamPapers.put(a1.examnumber,a1);
a1 = null;
}
}
else
{
wrong.add("wrong format:"+line);
}
}
else if (line.startsWith("#S:"))//获取答卷信息
{
AnswerPaper a = null;
Pattern p1 = Pattern.compile("#S:(\\d+)\\s(\\S+)");
Matcher m1 = p1.matcher(line);
if (m1.find())
{
a = new AnswerPaper(Integer.parseInt(m1.group(1)),m1.group(2));
line = line.replaceFirst("#S:\\d+\\s\\S+\\s+", "");
Pattern p2 = Pattern.compile("#A:(\\S+)-");
Pattern p3 = Pattern.compile("#A:(\\S+)-(\\S+)");
Matcher m2 = p2.matcher(line);
Matcher m3 = p3.matcher(line);
while (m2.find())
{
if(m3.find())
{
a.addAnswer(Integer.parseInt(m3.group(1)), m3.group(2));//存入试卷题目序号和题目答案
}
else
{
a.addAnswer(Integer.parseInt(m2.group(1)), "");//存入试卷题目序号和题目答案
}
}
}
else
{
wrong.add("wrong format:"+line);
}
AnswerPapers.add(a);
a = null;
}
else if(line.startsWith("#X:"))
{
Student a = null;
line = line.replaceFirst("#X:", "");
Pattern p1 = Pattern.compile("(\\d+)\\s(\\w+)");
Matcher m1 = p1.matcher(line);
while(m1.find())
{
a = new Student(m1.group(1),m1.group(2));
Students.put(a.num,a);
a = null;
}
}
else if(line.startsWith("#D:"))
{
Pattern p1 = Pattern.compile("N-(\\d+)");
Matcher m1 = p1.matcher(line);
while(m1.find())
{
del.add(Integer.parseInt(m1.group(1)));
}
}
else
{
if(line != null&&!line.isEmpty())
{
wrong.add("wrong format:"+line);
}
}
}
for(String a : wrong)
{
System.out.println(a);
}
for (Map.Entry<Integer,ExamPaper> entry : ExamPapers.entrySet())//打印是否试卷有100分
{
if(!entry.getValue().toString().equals(" "))
{
System.out.println(entry.getValue().toString());
}
}
for (AnswerPaper answerpaper : AnswerPapers)//答卷列表
{
int sum=0;
StringBuilder sb = new StringBuilder();
if(ExamPapers.containsKey(answerpaper.papernumber))//找到匹配的试卷
{
int t=1;//用t来表示试卷中题目顺序
for(Question question : ExamPapers.get(answerpaper.papernumber).questions)//试卷中题目顺序
{
if(answerpaper.answers.containsKey(t))//这个题目是否在答卷中存在
{
if(Issues.containsKey(question.number))//是否引用错误题号
{
if(del.contains(question.number))//是否题号被删除
{
sb.append("0 ");
System.out.println("the question "+ question.number+" invalid~0");
}
else
{
if(Issues.get(question.number).check(answerpaper.answers.get(t)))
{
sum=sum+question.score;
sb.append(question.score+" ");
}
else
{
sb.append("0 ");
}
System.out.println(Issues.get(question.number).toString(answerpaper.answers.get(t)));
}
}
else
{
sb.append("0 ");
System.out.println("non-existent question~0");
}
}
else//这个题目答案为空
{
sb.append("0 ");
System.out.println("answer is null");
}
t++;//指向下一题
}
if(Students.containsKey(answerpaper.num))//判断是否存在这个学号
{
String sb1=sb.toString().trim();
System.out.println(answerpaper.num+" "+Students.get(answerpaper.num).name+": "+sb1+"~"+sum);
}
else
{
System.out.println(answerpaper.num+" not found");
}
}
else//没找到这个答卷
{
System.out.println("The test paper number does not exist");
}
}
}
}

第三次大作业设计与分析:相比较前两次作业,这次题目提升难度非常之大,它新加了一个学生信息和删除题目的功能,这次题目错误比较多,所以非常难,这次不仅仅就加了一个学生类,还要正则表达式运用的非常熟悉,动态数组也要运用的非常熟悉,题目删除功能也非常难实现,让我不知所措,一开始完全没有思路,一直在画类图,把类与类之间的关系搞清楚,随着类图的画出来,题目也变得清晰起来,这次设计了五个类,一个题目类,一个试卷类,一个答卷类,一个分数类,一个学生类,在将类之间调用,实现各个功能,在主函数里面用多个for循环就可以写出来啦,这次运用的东西太复杂了。
采坑心得:对于字符串的比较,不要使用 == 运算符,而应使用 equals 方法。
数据库操作中,要注意处理异常情况,防止数据丢失或错误。
对于复杂的逻辑,要注意代码的可读性和可维护性,以便后续的修改和扩展。
避免在循环中创建新对象,可能会导致性能下降。
注意代码的封装,隐藏内部实现细节,提高代码的可重用性。
在进行性能优化时,要注意权衡性能和代码可读性。
改进建议:使用继承来减少类的数量,多使用哈希表。
5.总结
本阶段三次题目集综合性总结
在完成本次 Java 作业的过程中,我收获颇丰。
首先,通过实践,我更加深入地理解了 Java 的核心概念和语法。对类、对象、继承、多态等面向对象编程的特性有了更清晰的认识。
其次,在代码实现过程中,我遇到了一些问题并努力解决它们。这提升了我的问题解决能力和调试技巧。
我也意识到一些不足之处。例如,在代码的可读性和可维护性方面还有待提高。今后,我会更加注重代码的规范和注释,以便他人更好地理解和维护。
为了进一步提升自己的 Java 编程能力,我计划:
1. 深入学习 Java 的高级特性和常用框架。
2. 多做一些实际项目,积累经验。
3. 积极参与编程社区,与其他开发者交流和学习。
总之,通过这次 Java 作业,我不仅提高了编程能力,还明确了未来的学习方向。我将继续努力,不断提升自己的技术水平。
浙公网安备 33010602011771号