第一次PTA作业总结
《第一次博客》
一.答题判题程序-1
源码如下:
点击查看代码
import java.util.*;
public class Main{
public static void main(String[] args)
{
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
scanner.nextLine();
Testpaper[] testpaper=new Testpaper[num];
for(int i=0;i<num;i++)
{
String[] strings = scanner.nextLine().split("#");
String number = strings[1].substring(2);
String content = strings[2].substring(2);
String answer = strings[3].substring(2);
testpaper[i] = new Testpaper(number.trim(), content.trim(), answer.trim());
}
Testpaper testpaper1=new Testpaper("1","1","1");
for(int i=0;i<num-1;i++)
{ for(int j=0;j<num-1-i;j++)
{ if(Integer.parseInt(testpaper[j].getNumber())>Integer.parseInt(testpaper[j+1].getNumber()))
{ testpaper1=testpaper[j+1];
testpaper[j+1]=testpaper[j];
testpaper[j]=testpaper1;
}
}
}
String[] xsanswer=new String[num];
String[] str = scanner.nextLine().split(" ");
for(int i=0;i<num;i++)
{ xsanswer[i]=str[i].substring(3);
}
for(int i=0;i<num;i++)
{
System.out.print(testpaper[i].tostring());
System.out.println(xsanswer[i]);
}
for(int i=0;i<num;i++)
{
if (testpaper[i].getAnswer().equals(xsanswer[i])) {
if(i==num-1)
System.out.printf("true");
else
System.out.printf("true ");
} else {
if(i==num-1)
System.out.printf("false");
else
System.out.printf("false ");
}
}
}
}
class Student
{ private String xsanswer;
public Student(String xsanswer)
{ this.xsanswer=xsanswer;
}
public String getXsanswer() {
return xsanswer;
}
}
class Testpaper
{
private String number;
private String content;
private String answer;
public Testpaper(String number, String content, String answer) {
this.number = number;
this.content = content;
this.answer = answer;
}
public String getNumber() {
return number;
}
public String getContent() {
return content;
}
public String getAnswer() {
return answer;
}
public String tostring(){
return content+"~";
}
}
-
前言:
1>.代码主要功能:
试卷对象创建:代码定义了一个Testpaper类,包含试题编号、内容、和答案属性。程序从输入中读取试卷数目,并创建相应数量的Testpaper对象。 class Testpaper { private String number; private String content; private String answer; public Testpaper(String number, String content, String answer) { this.number = number; this.content = content; this.answer = answer; } public String getNumber() { return number; } public String getContent() { return content; } public String getAnswer() { return answer; } public String tostring(){ return content+"~"; } } 试卷排序:程序通过嵌套循环实现试卷数组testpaper的排序。排序的依据是试题的编号。 Testpaper testpaper1=new Testpaper("1","1","1"); for(int i=0;i<num-1;i++) { for(int j=0;j<num-1-i;j++) { if(Integer.parseInt(testpaper[j].getNumber())>Integer.parseInt(testpaper[j+1].getNumber())) { testpaper1=testpaper[j+1]; testpaper[j+1]=testpaper[j]; testpaper[j]=testpaper1; } } } 答案处理:程序从输入中读取学生的答案,并存储在xsanswer数组中。 String[] xsanswer=new String[num]; String[] str = scanner.nextLine().split(" "); for(int i=0;i<num;i++) { xsanswer[i]=str[i].substring(3); } 答案对比:程序通过比较试卷的正确答案和学生答案,打印每个试题的比较结果(true 或 false)。 for(int i=0;i<num;i++) { if (testpaper[i].getAnswer().equals(xsanswer[i])) { if(i==num-1) System.out.printf("true"); else System.out.printf("true "); } else { if(i==num-1) System.out.printf("false"); else System.out.printf("false "); } }
2>.主要知识点:
使用Scanner从标准输入中读取数据。 定义了类Testpaper来表示试卷,包括试题的编号、内容和答案。 使用嵌套循环实现对试卷数组的排序(基于试题编号)。 使用字符串处理(substring()和split()方法)来解析输入数据。 使用数组来存储试卷对象和学生的答案。 循环遍历试卷,打印试卷内容和学生答案,并对比答案得出true或false的结果。
3>.题目的题量:
本题的题目要求较少,只需构造三个类和编写少量的基础函数。
4>.题目难度:
本题的难度较为入门,只需大概知道类的基本构造就能完成。
-
设计与分析:
-
采坑心得:
1>.命名规范和代码风格:
类名的命名都不书面和规范,单词的开头大小写没u有区分,例如:Testpaper。 class Testpaper { } 方法名和变量名应该采用小驼峰命名法,即除了第一个单词外,其他单词的首字母大写,例如:getNumber() 而不是 getnumber()。 尽量避免使用单个字母的变量名,例如 num,除非它们是在循环中临时使用的计数器。 类名和方法名应该能够清晰地表达其功能和作用。
2>.缺少异常处理:
在读取用户输入时,应该考虑添加异常处理机制,比如在用户输入无效数据时,提示用户并重新请求输入。
3>.未使用的类和方法:
在代码中定义了 Student 类,我其实并没有用到,而是采用了其他方法存储这个类。 toString() 方法在 TestPaper 类中被定义,也没用使用,而是再主函数里面直接打印输出。
4>.算法的使用
对试卷进行排序时使用了冒泡排序,这种排序算法的效率较低,尤其是在大数据量情况下。
5>.代码逻辑:
对于比较答案的部分,多次调用 System.out.printf() 方法,多次打印输出,增加代码复杂度。
6>.注释:
在于一些比较复杂逻辑或算法的部分,基本没有什么注释
-
改进建议
在输入部分使用更具语义的变量名,可以提高代码可读性。例如将"num"改为"numberOfTests", 将"xsanswer"改为"studentAnswers"等。 可以将排序逻辑抽离为一个方法,增加代码的复用性并提高可读性。 可以使用ArrayList代替数组,以便更灵活地管理和操作数据。 在比较学生答案与正确答案时,可以使用StringBuilder来构建输出结果,而不是多次调用 System.out.printf()。 可以增加异常处理机制,如输入数据不合法或格式不正确时进行相应的提示或处理。 可以增加更多的注释来解释代码的逻辑和功能,以便他人更容易理解和维护代码。 可以优化算法,减少不必要的循环或操作,提高代码的性能和效率。 可以添加更多的功能,例如统计学生答题正确率,分析学生答题情况等,使程序更加完善和实用。
二.答题判题程序-2
源码如下:
点击查看代码
import java.util.*;
class Question {
int number;//题目编号
String content;//内容
String answer;//标准答案
public Question() {//初始化
}
public Question(int number, String content, String answer) {//初始化
this.number = number;
this.content = content;
this.answer = answer;
}
public void setNumber(int number) {
this.number = number;
}
public void setContent(String content) {
this.content = content;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public int getNumber() {
return number;//返回编号
}
public String getContent() {
return content;//返回内容
}
public String getAnswer() {
return answer;//返回标准答案
}
}
class TestPaper {//试卷题目类
int paperNumber;//试卷编号
List<NumberScore> NumberScores;
public TestPaper(int paperNumber) {
this.paperNumber = paperNumber;
this.NumberScores =new ArrayList<>();
}//初始化和创建map
public void setPaperNumber(int paperNumber) {
this.paperNumber = paperNumber;
}
public void setNumberScores( List<NumberScore> NumberScores) {
this.NumberScores = NumberScores;
}
public void addAumberScore(NumberScore numberScore) {//将题目的序号和对应分数写入
NumberScores.add(numberScore);
}
public int getPaperNumber()
{ return paperNumber;
}
public List<NumberScore> getNumberScores() {
return NumberScores;
}
}
class AnswerSheet {//学生答卷
int sheetNumber;//答卷编号
List<String> answers;//学生答案数组
public AnswerSheet(int SheetNumber) {//初始化
this.sheetNumber = sheetNumber;
this.answers = new ArrayList<>();
}
public void addAnswer(String answer) {//将每个题目的答案都存进去
answers.add(answer);
}
public void setSheetNumber(int sheetNumber) {
this.sheetNumber = sheetNumber;
}
public void setAnswers( List<String> answers) {
this.answers = answers;
}
public int getSheetNumber()
{ return sheetNumber;
}
}
class NumberScore
{
int number;
int score;
public NumberScore(int number,int score) {//初始化
this.number = number;
this.score= score;
}
public void setNumber(int number) {//初始化
this.number= number;
}
public void setScore(int Score) {//初始化
this.score= Score;
}
public int getNumber()
{ return number;
}
public int getScore()
{ return score;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<Integer, TestPaper> testPapers = new HashMap<>();//试卷编号——试卷
Map<Integer, List<AnswerSheet>> answerSheets = new HashMap<>();//答卷编号——答卷
//Map不能存两个键相同的答卷类
List<Question> questions = new ArrayList<>();//题目的数组
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.equals("end")) {
break;
}
if (line.startsWith("#N:")) {
String[] parts = line.split("#");
String number = parts[1].substring(2);
number=number.trim();
String content = parts[2].substring(2);
content=content.trim();
String answer = parts[3].substring(2);
answer=answer.trim();
Question a=new Question(Integer.parseInt(number), content, answer);
questions.add(a);
}
if (line.equals("end")) {
break;
}
if (line.startsWith("#S:")) {
String[] parts = line.split(" ");
int sheetNumber = Integer.parseInt(parts[0].substring(3));
AnswerSheet answerSheet=new AnswerSheet(sheetNumber);
for (int j = 1; j < parts.length; j++) {
answerSheet.addAnswer(parts[j].substring(3));
}
if (answerSheets.containsKey(sheetNumber))
answerSheets.get(sheetNumber).add(answerSheet);
else
{
List<AnswerSheet> list = new ArrayList<>();
list.add(answerSheet);
answerSheets.put(sheetNumber,list);
}
}
if (line.equals("end")) {
break;
}
if (line.startsWith("#T:")) {
String[] parts = line.split(" ");
int paperNumber = Integer.parseInt(parts[0].substring(3));
TestPaper testPaper = new TestPaper(paperNumber);
List<NumberScore> NumberScores=new ArrayList<>();
for (int i = 1; i < parts.length; i++) {
String[] questionScorePair = parts[i].split("-");
int questionNumber = Integer.parseInt(questionScorePair[0]);
int score = Integer.parseInt(questionScorePair[1]);
// System.out.println(questionNumber+" "+score);
NumberScore numberScore=new NumberScore(questionNumber,score);
NumberScores.add(numberScore);
}
testPaper.setNumberScores(NumberScores);
testPapers.put(paperNumber, testPaper);
}
if (line.equals("end")) {
break;
}
}
for (int paperNumber : testPapers.keySet()) {
TestPaper testPaper = testPapers.get(paperNumber);//创建遍历到的当前的试卷
int totalScore = 0;//总分
for(NumberScore numberScore :testPaper.getNumberScores())
{
totalScore = totalScore + numberScore.getScore();//求试卷总分
}
if (totalScore != 100) {
System.out.println("alert: full score of test paper" + paperNumber + " is not 100 points");
}//不是100则输出
}
for(int paperNumber : answerSheets.keySet())
{
if(!testPapers.containsKey(paperNumber))
{ System.out.println("The test paper number does not exist");}
else
{
TestPaper testPaper = testPapers.get(paperNumber);//创建遍历到的当前的试卷
List<Integer> questionscore = new ArrayList<>();//存储当前的试卷各题的分数
for(NumberScore numberScore :testPaper.getNumberScores())
{
questionscore.add(numberScore.getScore());
}
//在这里判断是否能不能找到对应的答卷编号
List<AnswerSheet> AnswerSheets = answerSheets.get(paperNumber);
//循环输出多个相同编号的答卷
for(int j = 0; j < AnswerSheets.size();j++){
AnswerSheet answerSheet = AnswerSheets.get(j);
List<Question> paperquestion = new ArrayList<>();//试卷里的题目
for(NumberScore numberScore :testPaper.getNumberScores())
{
//System.out.println(numberScore.getNumber()+" "+numberScore.getScore());
for(Question question : questions)
{
if(question.getNumber()==numberScore.getNumber())
{ paperquestion.add(question);
}
}
}
for (int i = 0; i < paperquestion.size();i++) {
Question question = paperquestion.get(i);
String answer = i < answerSheet.answers.size() ? answerSheet.answers.get(i) : "answer is null";
if(answer=="answer is null")
{ System.out.println("answer is null");
}
else
{
boolean isCorrect = answer.equals(question.answer);
System.out.println(question.content + "~" + answer + "~" + isCorrect);
}
}
int totalPaperScore = 0;
int a=1;
for (int i = 0; i < paperquestion.size();i++) {
Question question = paperquestion.get(i);
String answer = i < answerSheet.answers.size() ? answerSheet.answers.get(i) : "answer is null";
if(answer.equals(question.answer))
{ totalPaperScore=totalPaperScore+questionscore.get(i);
if(a==paperquestion.size())
System.out.print(questionscore.get(i));
else
System.out.print(questionscore.get(i)+" ");
}
else
{ totalPaperScore=totalPaperScore+0;
if(a==paperquestion.size())
System.out.print("0");
else
System.out.print("0 ");
}
a++;
}
System.out.printf("~%d\n",totalPaperScore);
}
}
}
}
}
-
前言:
1>.主要知识点:
面向对象编程:定义了题目 (Question)、试卷 (TestPaper)、答题卡 (AnswerSheet)、题号与分数 (NumberScore) 这几个类,并使用了类、对象、构造函数、成员变量、成员方法等面向对象的概念。 集合类:使用了 java.util.List 和 java.util.ArrayList 来存储题目序号与分数、学生的答案等信息。 Map<Integer, TestPaper> testPapers = new HashMap<>();//试卷编号——试卷 Map<Integer, List<AnswerSheet>> answerSheets = new HashMap<>();//答卷编号——答卷 //Map不能存两个键相同的答卷类 List<Question> questions = new ArrayList<>();//题目的数组 输入输出:使用了 Scanner 类来从标准输入中读取用户输入的文本。 集合类:使用了 java.util.HashMap 来存储试卷和答题卡的信息。 字符串处理:通过对输入文本的处理,提取出题目内容、答案等信息。 控制流:使用了 while 循环和 if 条件语句来处理输入文本的不同情况。 while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); if (line.equals("end")) { break; } if (line.startsWith("#N:")) { String[] parts = line.split("#"); String number = parts[1].substring(2); number=number.trim(); String content = parts[2].substring(2); content=content.trim(); String answer = parts[3].substring(2); answer=answer.trim(); Question a=new Question(Integer.parseInt(number), content, answer); questions.add(a); } if (line.equals("end")) { break; } if (line.startsWith("#S:")) { String[] parts = line.split(" "); int sheetNumber = Integer.parseInt(parts[0].substring(3)); AnswerSheet answerSheet=new AnswerSheet(sheetNumber); for (int j = 1; j < parts.length; j++) { answerSheet.addAnswer(parts[j].substring(3)); } if (answerSheets.containsKey(sheetNumber)) answerSheets.get(sheetNumber).add(answerSheet); else { List<AnswerSheet> list = new ArrayList<>(); list.add(answerSheet); answerSheets.put(sheetNumber,list); } } if (line.equals("end")) { break; } if (line.startsWith("#T:")) { String[] parts = line.split(" "); int paperNumber = Integer.parseInt(parts[0].substring(3)); TestPaper testPaper = new TestPaper(paperNumber); List<NumberScore> NumberScores=new ArrayList<>(); for (int i = 1; i < parts.length; i++) { String[] questionScorePair = parts[i].split("-"); int questionNumber = Integer.parseInt(questionScorePair[0]); int score = Integer.parseInt(questionScorePair[1]); // System.out.println(questionNumber+" "+score); NumberScore numberScore=new NumberScore(questionNumber,score); NumberScores.add(numberScore); } testPaper.setNumberScores(NumberScores); testPapers.put(paperNumber, testPaper); } if (line.equals("end")) { break; } } Java基础知识:包括循环、条件判断、集合操作等。 面向对象编程:使用了类和对象,比如TestPaper、NumberScore、AnswerSheet等。 集合操作:使用了ArrayList和HashMap等集合类来存储数据。 字符串操作:对字符串进行了比较和输出操作。 流程控制:通过条件判断来实现不同情况下的处理逻辑。
2>.题目的题量:
是一个较简单的试卷评分程序,主要功能是检查试卷总分是否为100分,然后与对应的答卷进行比较,计算得分并 输出,从循环结构和遍历集合的操作来看,可以处理较大规模的试卷和答卷,但是在比对过程中的细节很多,
3>.题目难度:
主要是分为两大类,和一小类,用于管理题目、试卷和答题卡的相关信息,没有涉及到复杂的算法或业务逻辑。 代码的难度适中。主要涉及输入输出、字符串处理和基本的集合操作,不涉及复杂的算法或业务逻辑。 尽管代码较长,但主要是由于需要处理不同格式的输入,并根据输入构建相应的数据结构,而这些都是基本的编程技 从代码逻辑和功能来看,代码整体难度不高,主要是对数据的遍历和逻辑判断。 难点可能在于对集合数据的处理和对试卷、答卷关联逻辑的理解。 总的来说,属于面向对象的基础知识,适合初学者学习和理解面向对象编程的概念和集合类的使用。 适合用于学习输入输出处理、字符串操作和集合类的使用。 是一个较为简单的试卷评分程序,主要功能是检查试卷总分是否为100分,然后与对应的答卷进行比较,计算得分并 输出。虽然没有直接给出题量和难度等信息,但从代码逻辑和功能来看,它是一个用于批量评分的简单工具。
-
设计与分析:
-
采坑心得:
1>.代码风格和命名规范:类名、变量名、方法名不规范和书面,没有保持一致性和可读性。 类中的注释不太详细,注释较少,没有说明每个方法的作用和参数含义。
2>.不一致的变量命名:
在 AnswerSheet 类中,构造函数参数为 SheetNumber,但在类中使用的是 sheetNumber,没有保持一致。 类中使用的 NumberScores 在 TestPaper 类中初始化时应该命名为 numberScores,保持一致性。
3>.缺少异常处理:
目前代码中没有对异常情况进行处理,比如当试卷题目的编号或内容为空时应该如何处理等。
4>.缺少输入检查和验证:
在类的方法中缺少对输入参数的检查和验证,比如是否为有效的题号、答案是否为空等。
5>.缺少文档注释:
类和方法应该没有添加文档注释,清楚说明其作用、参数含义以及返回值。
6>.缺少评分逻辑:
目前代码中缺少对学生答卷的评分逻辑,需要根据学生答案与标准答案进行比较,并计算得分。
7>.部分方法功能冗余:
在 Question 类中的 setNumber、setContent、setAnswer 方法功能与构造函数重复,没有考虑是否需要保留。
8>.缺少方法重载:
在 TestPaper 类中没有考虑添加重载方法,以便在添加题目时能够同时设置题目的序号和分数。
9>.类中函数的构造:
应该考虑在 AnswerSheet 类中添加方法来进行答案比对和自动评分,以提高代码的封装性和可复用性。
10>. 重复代码:
代码中存在多处重复的判断条件和逻辑,比如判断输入是否为"end"时,重复了多次。
11>.逻辑错误:
在处理输入时,多次判断是否为"end",但实际上在前面已经有一个判断了,应该只在一个地方处理。
12>.变量命名不规范:
一些变量命名不够清晰,比如a、parts等。
13>.错误的字符串处理:
在处理题目、答卷和试卷信息时,使用了不够严谨的字符串分割方法,可能会导致在实际输入中出现问题。
14>.数据结构的使用不当:
在存储答卷信息时,使用了Map<Integer, List<AnswerSheet>>,但这样做可能会导致后续难以查询或者更新答卷信 息。
15>.缺乏异常处理:
对于一些可能导致异常的操作(比如类型转换),没有进行异常处理。
16>.缺乏注释:
代码中缺乏注释,不易于理解和维护。
17>.缺少输入合法性检查:
没有对输入进行合法性检查,比如对于数字的转换是否会导致异常。
18>.潜在的性能问题:
在每次迭代中都判断是否为"end",这样做在输入规模较大时可能会影响性能。
19>.部分逻辑可以抽象成函数:
将部分逻辑抽象成函数可以提高代码的可读性和可维护性。
20>.未处理题目不存在或者试卷编号重复的情况:
在处理题目和试卷时没有考虑到题目编号或试卷编号可能重复的情况,也没有检查题目是否存在。
21>.字符串比较问题:
在 Java 中,字符串比较应该使用 equals() 方法而不是 == 操作符。所以,比较字符串时应该使用 answer.equals("answer is null") 而不是 answer == "answer is null"。
22>.不恰当的字符串连接:
在 Java 中,字符串连接可以使用 + 操作符,但是在循环中频繁的使用 + 操作符来连接字符串会导致性能问题,尤其 是在大量数据时。可以使用 StringBuilder 类来优化字符串连接操作。
23>.不必要的列表迭代:
在某些地方,可能存在不必要的列表迭代,例如,在计算试卷总分时,在第二次循环中也再次迭代试题。这可能会导致 性能下降。
24>.潜在的空指针异常:
没有对 answerSheet.answers 的长度和 paperquestion 的长度进行比较,如果两者不匹配,可能会导致数组越界 异常。
25>.逻辑错误:
在输出每个问题的得分时,可能需要考虑是否需要在最后一个问题后面添加空格。
26>.使用字符串常量进行比较:
在条件语句中使用字符串常量进行比较,如 "answer is null",这样不仅效率低下,而且容易出错。推荐使用布尔值 或者特定的标志来代表空值状态。
27>.可读性和维护性:
这段代码的可读性较低,难以理解,尤其是在多重嵌套循环和条件语句中。可以考虑将其拆分为更小的方法或者增加注 释来提高可读性和维护性。
28>.错误处理:
没有对可能出现的异常情况进行处理,比如试卷编号不存在的情况。
-
改进建议:
对于三个类的构造这部分的代码有一下的可以改进的方面: 命名规范和注释:虽然代码中存在注释,但是一些方法和变量的命名可以更具体和清晰,使得代码更易读懂。例如,在 TestPaper类中,addAumberScore方法的名字中有个拼写错误,应该是addNumberScore。另外,一些注释可以更详细 一些,例如,解释一些复杂逻辑或不明确的部分。 异常处理:在代码中没有对可能的异常情况进行处理。例如,在TestPaper类的构造函数中,可能需要检查传入的参数 是否合法,是否为负数。 数据验证:在向试卷和答卷中添加题目和答案时,没有进行数据的验证,例如,题目编号是否已存在、答卷中的答案是 否符合题目要求等。可以在添加数据之前进行一些验证。 封装性:虽然已经定义了一些基本的 getter 和 setter 方法,但是仍可以进一步提高封装性,例如,在TestPaper类 中,可能不希望直接暴露 NumberScores 列表,而是提供一些方法来操作该列表,从而更好地控制数据的访问。 可扩展性:目前代码中只实现了基本功能,如果未来需要添加更多的功能,例如计算答卷得分或输出结果,可以在设计 时考虑更好地支持扩展。 代码结构:目前所有的类都定义在了同一个文件中,如果代码规模继续增长,可以考虑将每个类放在单独的文件中,以 提高代码的可维护性和可读性。 通过对以上方面对与三个类的构造改进,使第一部分构造类的代码更加健壮、易读和易于扩展。 对于输入这一大块的代码有一下的问题方面可以改进升级: 重复代码处理:在处理输入行是否为"end"时,出现了多次相同的代码段,可以将这部分代码提取出来,避免重复。 键的提取:在解析以"#“或”#S:"开头的行时,提取键的方式有点复杂。可以通过更简洁的方式来提取键值,例如使用正 则表达式。 数据结构的选择:在存储答卷时,使用了Map<Integer, List<AnswerSheet>>,而在检查是否存在相同键的答卷时, 需要进行一些额外的操作。这可能会增加复杂性。考虑是否有更合适的数据结构可以使用,以简化代码逻辑。 输入数据的验证:在解析输入时,没有对输入数据进行验证,例如对数字的有效性、输入行的格式等进行检查,这可能 导致程序在遇到无效输入时出现异常。 异常处理:在将字符串转换为数字时,没有处理可能的NumberFormatException异常,建议在这些地方加入异常处理逻 辑。 变量命名:一些变量命名不够清晰,例如"parts"、"a"等,建议使用更具描述性的名称来增加代码的可读性。 注释:虽然代码已经相当清晰,但添加一些注释来解释代码的功能和意图将有助于更好地理解代码。 代码段合并:在检查是否为"end"时,可以将这部分代码段合并,只需在循环外部进行一次检查即可。 字符串处理:在处理输入行时,可能会遗漏一些特殊情况,例如行首尾可能包含空格或制表符。可以使用trim()函数来 处理这些情况,以确保数据的准确性。 异常情况处理:在处理输入时,可能会遇到一些意外情况,例如输入行格式错误等,建议添加适当的异常处理机制来应 对这些情况。 对于打印匹对答案这一大部分有一下的问题可以改进和提升: 使用增强型循环遍历集合:在Java 5及更高版本中,增强型for循环可以使代码更简洁,更易读。 for (TestPaper testPaper : testPapers.values()) { // Do something with testPaper } 使用Map.containsKey()检查键是否存在:在第一个循环中,可以使用containsKey()来检查键是否存在,而不是直接 通过get()方法获取值并检查是否为null。 for (int paperNumber : answerSheets.keySet()) { if (!testPapers.containsKey(paperNumber)) { System.out.println("The test paper number does not exist"); } else { // Proceed with existing paperNumber } } 使用StringBuilder拼接字符串:在需要拼接大量字符串时,使用StringBuilder比直接使用+运算符更高效。 StringBuilder message = new StringBuilder(); message.append("alert: full score of test paper ").append(paperNumber).append(" is not 100 points"); System.out.println(message.toString()); 避免使用==比较字符串:在Java中,字符串比较应该使用equals()方法而不是==运算符。 if ("answer is null".equals(answer)) { System.out.println("answer is null"); } 合并相似的循环:在内部循环中,有几处相似的代码可以合并,以减少重复。 for (int i = 0; i < paperquestion.size(); i++) { Question question = paperquestion.get(i); String answer = (i < answerSheet.answers.size()) ? answerSheet.answers.get(i) : "answer is null"; // Code for checking correctness and printing } for (int i = 0; i < paperquestion.size(); i++) { // Code for calculating totalPaperScore } 简化条件语句:在一些地方可以使用三元运算符或简化的if语句来减少代码量。 提取重复逻辑为方法:如果有重复的逻辑,可以将其提取为单独的方法以提高代码的重用性和可读性。 添加注释:对于复杂的逻辑或者代码的关键部分,添加一些注释来解释其用途和实现细节,有助于其他人理解代码。 错误处理:在处理用户输入或者外部数据时,应该考虑错误情况,例如空指针或者数据格式错误等,添加适当的错误处 理。 单一职责原则:确保每个方法或者代码块只负责一个功能,这样可以提高代码的可维护性和可读性。 异常处理:在可能发生异常的地方添加适当的异常处理,以确保程序的稳定性和健壮性。 代码重构:定期进行代码重构,优化代码结构,提高代码的可读性和性能。 这些改进措施可以使代码更加高效、可读、易于维护和扩展。
三.答题判题程序-3
源码如下:
点击查看代码
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Question {
int number;//题目编号
String content;//内容
String answer;//标准答案
public Question(int number, String content, String answer) {//初始化
this.number = number;
this.content = content;
this.answer = answer;
}
public int getNumber() {
return number;//返回编号
}
public String getContent() {
return content;//返回内容
}
public String getAnswer() {
return answer;//返回标准答案
}
}
class TestPaper {//试卷题目类
int paperNumber;//试卷编号
List<NumberScore> NumberScores;
public TestPaper(int paperNumber) {
this.paperNumber = paperNumber;
this.NumberScores =new ArrayList<>();
}//初始化和创建map
public void addAumberScore(NumberScore numberScore) {//将题目的序号和对应分数写入
NumberScores.add(numberScore);
}
public List<NumberScore> getNumberScores() {
return NumberScores;
}
}
class AnswerSheet {//学生答卷
int sheetNumber;//答卷编号
String studentID;//学生学号
Map<Integer, String> answers;//学生答案数组
//////写到这里
public AnswerSheet(int SheetNumber,String studentID) {//初始化
this.sheetNumber = sheetNumber;
this.studentID=studentID;
this.answers = new HashMap<>();
}
public void addAnswer(int ordernumber,String answer) {//将每个题目的答案都存进去
answers.put(ordernumber,answer);
}
public String getStudentID()
{ return studentID;
}
public Map<Integer, String> getAnswers()
{ return answers;
}
}
class NumberScore
{
int number;
int score;
public NumberScore(int number,int score) {//初始化
this.number = number;
this.score= score;
}
public int getNumber()
{ return number;
}
public int getScore()
{ return score;
}
}
class OrderAnswer
{
int ordernumber;
String answer;
public OrderAnswer(int ordernumber,String answer) {//初始化
this.ordernumber = ordernumber;
this.answer= answer;
}
public int getOrdernumber()
{ return ordernumber;
}
public String getAnswer()
{ return answer;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<Question> questions = new ArrayList<>();//题目的数组
Map<Integer, TestPaper> testPapers = new HashMap<>();//试卷编号——试卷
Map<Integer, List<AnswerSheet>> answerSheets = new HashMap<>();//答卷编号——答卷
Map<String, String> students = new HashMap<>();//学号——姓名
List<Integer> deletes = new ArrayList<>();//删除的题目
//Map不能存两个键相同的答卷类
int n=200;
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.equals("end")) {
break;
} else if (line.startsWith("#N:")) {
String regex = "^#N:(.*) #Q:(.*) #A:(.*)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
if(matcher.matches())
{
String[] parts = line.split("#");
String number = parts[1].substring(2);
number=number.trim();
String content = parts[2].substring(2);
content=content.trim();
String answer = parts[3].replace("A:", "");
if(answer!=null)
{ answer=answer.trim();
// System.out.println(answer+" a");
Question a=new Question(Integer.parseInt(number), content, answer);
questions.add(a);
}
else
{ String result = answer.replace("","yes");
answer=result;
System.out.println(answer+" b");
Question a=new Question(Integer.parseInt(number), content, answer);
questions.add(a);
}
}
else
{ System.out.println("wrong format:"+line);
}
} else if (line.startsWith("#T:")) {
Pattern patternTest = Pattern.compile("^#T:\\d+ \\d+-\\d+( \\d+-\\d+)*$");
Matcher matcherTest= patternTest.matcher(line);
if(matcherTest.find())
{
String[] parts = line.split(" ");
int paperNumber = Integer.parseInt(parts[0].substring(3));
TestPaper testPaper = new TestPaper(paperNumber);
for (int i = 1; i < parts.length; i++) {
String[] questionScorePair = parts[i].split("-");
int questionNumber = Integer.parseInt(questionScorePair[0]);
int score = Integer.parseInt(questionScorePair[1]);
// System.out.println(questionNumber+" "+score);
NumberScore numberScore=new NumberScore(questionNumber,score);
testPaper.addAumberScore(numberScore);
}
testPapers.put(paperNumber, testPaper);
}
else
{ System.out.println("wrong format:"+line);
}
} else if (line.startsWith("#S:")) {
String[] parts = line.split("#");
String parts1 = parts[1].substring(2);
String[] parts2 = parts1.split(" ");
int sheetNumber = Integer.parseInt(parts2[0]);
String studentID = parts2[1];
AnswerSheet answerSheet=new AnswerSheet(sheetNumber,studentID);
for (int i = 2; i < parts.length; i++) {
String a = parts[i].substring(2);
String a1 = a.trim();
String[] orderanswer = a1.split("-");
int ordernumber = Integer.parseInt(orderanswer[0]);
String answer = orderanswer.length > 1 ? orderanswer[1] : "";
if(answer!= null)
{ answerSheet.addAnswer(ordernumber,answer);
// System.out.println(answer+" a");
}
else
{ String result = answer.replace("","yes");
answer=result;
// System.out.println(answer+" b");
answerSheet.addAnswer(ordernumber,answer);
}
}
if (answerSheets.containsKey(sheetNumber))
{
answerSheets.get(sheetNumber).add(answerSheet);
} else
{
List<AnswerSheet> list = new ArrayList<>();
list.add(answerSheet);
answerSheets.put(sheetNumber,list);
}
}else if (line.startsWith("#X:")) {
String ab=line.substring(3);
String[] parts = ab.split("-");
for (int i = 0; i < parts.length; i++) {
String[] IDname = parts[i].split(" ");
students.put(IDname[0], IDname[1]);
//System.out.println(IDname[0]+" "+IDname[1]);
}
}else if (line.startsWith("#D:")) {
String line1=line.substring(3);
String[] parts = line1.split(" ");
for (int i = 0; i < parts.length; i++) {
String[] number = parts[i].split("-");
deletes.add(Integer.parseInt(number[1]));
}
}else
{
System.out.println("wrong format:"+line);
}/* if(line.contains("Q")||line.contains("A")){
System.out.println("wrong format:"+line);
} else if(line.contains("T")){
System.out.println("wrong format:"+line);
} else if(line.contains("S")){
System.out.println("wrong format:"+line);
} else if(line.contains("D")){
System.out.println("wrong format:"+line);
}*/
/*else {
//这里判断试卷输入错误测试点17
String regex = "\\b\\S+-\\S+\\b";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
if(matcher.find()&&!line.contains("#A"))
{
System.out.println("wrong format:"+line);
}
}*/
}
for (int paperNumber : testPapers.keySet()) {
}
//第一次循环为了打印是否为满分卷
for (int paperNumber : testPapers.keySet()) {
TestPaper testPaper = testPapers.get(paperNumber);//创建遍历到的当前的试卷
int totalScore = 0;//总分
for(NumberScore numberScore :testPaper.getNumberScores())
{
totalScore += numberScore.getScore();//求试卷总分
}
if (totalScore != 100) {
System.out.println("alert: full score of test paper" + paperNumber + " is not 100 points");
}//不是100则输出
}
//第二次循环打印分数
for(int paperNumber : answerSheets.keySet())
{ //在这里判断是否能不能找到对应的答卷编号
if(!testPapers.containsKey(paperNumber))
{ System.out.println("The test paper number does not exist");}
else
{
TestPaper testPaper = testPapers.get(paperNumber);//创建遍历到的当前的试卷
List<Integer> questionscore = new ArrayList<>();//存储当前的试卷各题的分数
for(NumberScore numberScore :testPaper.getNumberScores())
{
questionscore.add(numberScore.getScore());
}
List<AnswerSheet> AnswerSheets = answerSheets.get(paperNumber);
//循环输出多个相同编号的答卷
for(int j = 0; j < AnswerSheets.size();j++){
AnswerSheet answerSheet = AnswerSheets.get(j);
//存储本次检索试卷里的题目
for(int ordernumber : answerSheet.answers.keySet())
{ if(ordernumber>testPaper.NumberScores.size())
answerSheet.answers.remove(ordernumber);
}
List<Question> paperquestion = new ArrayList<>();
int l=100;
for(NumberScore numberScore :testPaper.getNumberScores())
{
Question targetQuestion = null;
for(Question question : questions)
{
if(question.getNumber()==numberScore.getNumber())
{ targetQuestion = question;
paperquestion.add(question);
break;
}
}
if (targetQuestion == null) {
paperquestion.add(new Question(l,"delete","delete"));
l++;
}
}
//for(OrderAnswer orderanswer : answerSheet.getAnswers())
// { studentanswers.add(orderanswer.getAnswer());
// System.out.println(orderanswer.getAnswer());
// }
//打印1+1=~5~false
for (int i = 0; i < paperquestion.size();i++) {////在这
// int i=orderanswer.getOrdernumber();
Question question = paperquestion.get(i);
String answer = i < answerSheet.answers.size() ? answerSheet.answers.get(i+1) : "answer is null";
if(answer=="answer is null")
{ System.out.println("answer is null");
}
else
{ if(!deletes.contains(question.getNumber()))
{ if(question.getNumber()>=100)
{ System.out.println("non-existent question~0");
}
else
{boolean isCorrect = answer.equals(question.answer);
System.out.println(question.content + "~" + answer + "~" + isCorrect);
}
}
else
{
System.out.println("the question "+question.getNumber()+" invalid~0");
}
}
}
// 打印20201103 Tom: 0 0~0
// 使用get方法查找学号对应的姓名
String studentname = students.get(answerSheet.getStudentID());
// 输出结果
if (studentname != null)
{
System.out.print(answerSheet.getStudentID()+" "+studentname+": ");
int totalPaperScore = 0;
int a=1;
for (int i = 0; i < paperquestion.size();i++) {
Question question = paperquestion.get(i);
String answer = i < answerSheet.answers.size() ? answerSheet.answers.get(i+1) : "answer is null";
if(answer.equals(question.answer)&&!deletes.contains(question.getNumber()))
{ if(question.getNumber()>=100)
{
totalPaperScore=totalPaperScore+0;
if(a==paperquestion.size())
System.out.print("0");
else
System.out.print("0 ");
}
else
{
totalPaperScore=totalPaperScore+questionscore.get(i);
if(a==paperquestion.size())
System.out.print(questionscore.get(i));
else
System.out.print(questionscore.get(i)+" ");
}
}
else
{ totalPaperScore=totalPaperScore+0;
if(a==paperquestion.size())
System.out.print("0");
else
System.out.print("0 ");
}
a++;
}//
System.out.printf("~%d\n",totalPaperScore);
} else
{
System.out.print(answerSheet.getStudentID()+" not found");
continue;
}
}//相同卷号的else结束
}//判断是否能查找到卷号的else结束
}//for循环结束
}
}
- 前言:
1>.代码主要功能:
1. Question 类:
属性:
number:题目编号
content:题目内容
answer:标准答案
方法:
Question(int number, String content, String answer):构造方法,用于初始化题目对象。
int getNumber():获取题目编号。
String getContent():获取题目内容。
String getAnswer():获取标准答案。
2. TestPaper 类:
属性:
paperNumber:试卷编号
NumberScores:存储题目编号和分数对应关系的列表
方法:
TestPaper(int paperNumber):构造方法,用于初始化试卷对象。
void addAumberScore(NumberScore numberScore):添加题目的序号和对应分数。
List<NumberScore> getNumberScores():获取题目-分数对列表。
3. AnswerSheet 类:
属性:
sheetNumber:答卷编号
studentID:学生学号
answers:存储题目编号和学生答案对应关系的 Map
方法:
AnswerSheet(int SheetNumber,String studentID):构造方法,用于初始化答卷对象。
void addAnswer(int ordernumber,String answer):添加每个题目的学生答案。
String getStudentID():获取学生学号。
Map<Integer, String> getAnswers():获取题目编号和学生答案对应关系的 Map。
4. NumberScore 类:
属性:
number:题目编号
score:题目分数
方法:
NumberScore(int number,int score):构造方法,用于初始化题目编号和分数对象。
int getNumber():获取题目编号。
int getScore():获取题目分数。
题目类 (Question):包含题目编号、内容和标准答案,提供方法来获取这些信息。
试卷类 (TestPaper):包含试卷编号和题目-分数对应关系,提供方法来添加题目和获取题目-分数对。
学生答卷类 (AnswerSheet):包含答卷编号、学生学号以及学生的答案,提供方法来添加答案和获取学生学号和答案。
题目-分数对类 (NumberScore):用于存储题目编号和分数的对应关系。
这些类共同实现了一个简单的题目、试卷和学生答卷管理系统,允许用户创建题目、试卷和学生答卷,并进行相应的操作,
如添加题目、获取试卷内容、添加学生答案等。
解析题目信息:通过 #N: 开头的行解析题目编号、题目内容和正确答案,并将其存储到 questions 列表中。
解析试卷信息:通过 #T: 开头的行解析试卷编号和每道题目的分数,并将其存储到 testPapers 映射中。
解析学生答卷:通过 #S: 开头的行解析学生答卷编号、学生ID以及每道题目的答案,并将其存储到 answerSheets 映射
中。
解析学生信息:通过 #X: 开头的行解析学生ID和学生姓名,并将其存储到 students 映射中。
删除题目:通过 #D: 开头的行解析需要删除的题目编号,并将其存储到 deletes 列表中。
检查试卷总分是否为100分:首先,它遍历了一个试卷列表,计算每张试卷的总分,如果总分不等于100,则输出相应警告
信息。
比对答题卡与试卷的答案:然后,它再次遍历答题卡列表,逐个比对答题卡中的答案与试卷的标准答案。如果有不符合的情
况,输出相应信息。
输出学生得分:根据比对的结果,输出每个学生的得分情况,包括学生的姓名、答题情况以及得分情况。
输入扫描器初始化:通过 Scanner(System.in) 创建了一个输入扫描器,用于从标准输入流读取用户的输入。
题目管理:使用 ArrayList<Question> 存储题目对象的列表,用于管理题目的增删改查操作。
试卷管理:利用 HashMap<Integer, TestPaper> 存储试卷编号和对应试卷对象的映射关系,可以进行试卷的管理和生
成。
答卷管理:通过 HashMap<Integer, List<AnswerSheet>> 存储答卷编号和对应答卷列表的映射关系,用于记录学生的答
卷情况。
学生信息管理:使用 HashMap<String, String> 存储学生的学号和对应的姓名,用于学生信息的管理和查询。
题目删除记录:利用 List<Integer> deletes 存储删除的题目编号,可能用于后续的恢复操作或者记录历史删除记录。
2>.主要知识点:
使用类和对象进行面向对象编程。
使用集合类 ArrayList 和 HashMap 存储数据。
理解构造方法的作用,进行对象初始化。
了解基本的数据结构设计和实现。
正则表达式:用于解析不同格式的行。
集合和映射操作:包括列表、映射等数据结构的创建、访问和更新。
字符串操作:包括分割字符串、替换字符串等。
异常处理:对不符合格式的行进行错误处理。
Java基础知识:使用了Java中的循环、条件语句、集合等基本语法和数据结构。
集合操作:使用了HashMap和ArrayList来存储试卷、答题卡以及相关信息。
面向对象编程:定义了TestPaper、NumberScore、AnswerSheet、Question等类来组织数据,并通过类的方法来获取数
据或进行操作。
输入输出:通过 Scanner(System.in) 创建输入扫描器,实现用户输入的读取。
集合框架:使用了Java集合框架中的几种数据结构:
ArrayList<Question>:用于存储题目对象的动态数组。
HashMap<Integer, TestPaper>:用于存储试卷编号和对应试卷对象的映射关系。
HashMap<Integer, List<AnswerSheet>>:用于存储答卷编号和对应答卷列表的映射关系。
HashMap<String, String>:用于存储学生的学号和姓名的映射关系。
List<Integer>:用于存储删除的题目编号的动态数组。
面向对象编程:定义了题目、试卷、答卷对象,并使用集合来管理这些对象之间的关系。
程序逻辑:实现了对题目、试卷、答卷和学生信息的增删改查操作,以及题目删除的记录。
异常处理:虽然没有在代码中显式展示,但通常在使用 Scanner 进行输入时,需要考虑异常处理,例如
NoSuchElementException 或 InputMismatchException。
基本语法:包括变量声明、集合的初始化、注释等基本语法知识。
3>.题目的题量:
从代码结构来看,处理了试卷和答题卡的关系,并对每个学生的每道题目进行了评分和输出,有大量的数据处理,本题考虑
的要点特别多,可以出现的情况有很多种可以是,所以有特别多的循环嵌套和函数的调用,在本题中含有大量的数据试卷答
卷和删除题目等等都需要同时处理,所以总体来说的题目题量很多比较庞大。
4>.题目难度:
代码难度较有难度。涉及了一系列集合操作、条件判断和循环,同时也考察了对面向对象编程的理解。需要注意的是,代码
中有一些逻辑判断和循环嵌套,需要仔细理解逻辑关系和数据流动,有很多的细节需要考虑,在输入方面主要要使用正则表
达式来判断是否符合标准,其次是数据的处理主要是使用了hasMap的键值对和list的动态数组去存储,最后输出的时候循
环较多,复杂程度较高,难度较难。
- 设计与分析:
-
采坑心得:
变量命名不规范:在 AnswerSheet 类中的构造函数中,SheetNumber 应该为 sheetNumber,保持命名一致性。 类成员命名不清晰:NumberScore 类中的 number 和 score 变量名不够清晰,可以考虑改成 questionNumber 和 questionScore 等更具表达性的名称。 空指针异常风险:在 AnswerSheet 类中的 addAnswer 方法中,没有对传入的 answer 参数进行空指针检查,如果 answer 为 null,可能会导致空指针异常。 未使用的属性:AnswerSheet 类中的 sheetNumber 属性似乎没有被使用,如果没有其他用途,可以考虑移除或者在构 造函数中正确赋值。 缺少异常处理:在 TestPaper 类中的 addNumberScore 方法中,没有对传入的 numberScore 参数进行空指针检 查,如果为 null 可能会导致空指针异常。 缺少方法注释:部分方法缺少注释,例如 addAnswer、getStudentID 等,建议添加方法注释以提高代码的可读性和维 护性。 构造函数命名与类名不一致:AnswerSheet 类中的构造函数的参数为 SheetNumber,应该与类名一致,为 sheetNumber。 方法名拼写错误:在 TestPaper 类中,addAumberScore 方法拼写错误,应该为 addNumberScore。 输入验证不完整:虽然你做了一些输入格式的验证,但是并不完整。对于输入的每一行,都应该有严格的格式要求,而 且应该对用户输入的内容进行更全面的检查。 异常处理:在出现格式错误时,你只是简单地输出了一条错误信息,而没有提供更具体的信息或采取任何其他操作。在· 实际应用中,你可能需要更加健壮的异常处理机制,比如记录错误信息、提示用户重新输入等。 代码结构和命名规范:虽然代码基本功能实现了,但是代码结构和命名规范有待改进。更清晰的变量名和方法名会让代 码更易读,也更易于维护和扩展。 缺少注释:虽然你的代码中有一些注释,但是并不够详细。在实际项目中,良好的注释是必不可少的,特别是对于复杂 的业务逻辑或算法。 数据结构选择:你选择了适当的数据结构来存储题目、试卷、答卷等信息,但是在实际应用中,还需要考虑数据结构的 性能和内存占用情况。 逻辑问题:在读取答卷信息时,你使用了一个 Map<Integer, List<AnswerSheet>> 来存储答卷,但是这样的数据结 构可能会导致内存占用过高。考虑是否有更好的方法来组织数据。 代码重复:你的代码中存在一些重复的逻辑,比如读取题目信息和试卷信息时都有类似的处理逻辑,可以考虑将这些逻 辑抽取出来,避免重复编写相似的代码。 缺少单元测试:在实际项目中,单元测试是保证代码质量的重要手段之一。你的代码中缺少单元测试,这会增加代码修 改和维护的风险。
-
改进建议:
这段代码主要实现了一个简单的试卷管理系统,但还有一些改进的地方: 异常处理:目前代码中没有对输入的格式错误进行详细处理,你可以考虑增加更多的异常处理,比如对于无效输入格式 给出更具体的提示,以提高代码的健壮性。 代码重构:代码中有一些重复的部分,可以考虑将重复的逻辑提取出来,形成独立的方法或函数,以提高代码的可读性 和维护性。 命名规范:变量命名不够清晰,建议使用更具描述性的变量名,以增强代码的可读性。比如,scanner 可以改成 inputScanner,parts 可以改成 lineParts 等。 数据结构选择:在一些地方可以考虑是否选择更合适的数据结构。比如,是否有必要使用 HashMap 存储答卷编号和答 卷的映射关系?或者是否可以使用更适合的数据结构提高效率? 注释:代码中虽然有一些注释,但还可以进一步完善,对于一些复杂的逻辑或者关键的处理步骤,添加更详细的注释, 以便于他人理解你的代码。 单一职责原则:尽量保持每个方法的功能单一,这样可以提高代码的可读性和可维护性。 输入验证:对于从用户输入获取的数据,尤其是转换成数字的部分,应该进行输入验证,确保程序的健壮性。 使用equals方法比较字符串:在Java中,应该使用equals方法而不是==来比较字符串内容。所以在比较字符串answer 和"answer is null"时应该使用equals方法。 提取重复代码为方法:有一些代码段在两个地方重复出现,比如对问题是否为无效问题的判断逻辑,可以将其提取为一 个独立的方法,以减少代码的冗余性。 避免魔法数值:在代码中有一些魔法数值,如100,应该使用有意义的常量或变量名来替代,提高代码的可读性和可维 护性。 使用增强for循环:在遍历集合时,可以考虑使用增强for循环,提高代码的简洁性和可读性。 代码注释:虽然代码中有些注释,但并不是非常清晰,可以进一步提高注释的质量,以便更好地理解代码逻辑。 命名规范:变量名和方法名最好采用驼峰命名规范,使得代码更易读。 使用StringBuilder拼接字符串:在循环中拼接字符串时,最好使用StringBuilder,而不是直接使用"+",这样效率 更高。 错误处理:如果有可能,应该考虑添加异常处理机制,比如对集合下标的越界情况进行处理。 逻辑优化:可以考虑简化逻辑,减少嵌套层次,提高代码的可读性和可维护性。 测试和调试:在修改代码之后,要确保进行测试和调试,以确保修改没有引入新的错误。
四.三次题目的最后大总结:
对于这三次的答题模拟测试联系,我基本掌握了类基本函数并运用,通过这三次的答题练习我从开始对类的概念的模糊印象逐渐变得具体,更加深刻的了解了类到底是个什么这三次的代码的还有很多可以改进的地点与方面,由于提交的时间比较紧促,在设计代码的主要思路上没有太下功夫,导致的我的代码的流程不是较为清晰,而是想到什么步骤就写什么步骤,所以我根据我的代码的问题和踩的坑有一下新的思路想法是,模块化代码:将代码分成更小的函数或模块,提高可读性和可维护性。例如,将不同功能的代码块封装成函数,如处理题目信息、试卷信息、学生答卷信息等。
异常处理:当前代码似乎没有考虑到输入格式错误的情况,建议加入异常处理机制,对输入的格式进行验证,确保程序能够正确处理各种情况,避免因为输入格式错误导致程序崩溃或出现意外行为。
优化数据结构:当前使用了多个Map来存储题目、试卷、学生答卷等信息,可以考虑是否有更合适的数据结构来存储这些信息,以提高查询、操作的效率。例如,是否可以将学生答卷信息直接关联到对应的试卷上,而不是通过编号关联。
提高代码健壮性:在处理输入时,要考虑到各种可能的异常情况,比如数组越界、类型转换错误等,要做好相应的边界检查和异常处理,以保证程序的健壮性。添加更多功能:根据实际需求,可以进一步完善功能,比如计算学生的得分、生成试卷统计报告、支持更复杂的题型等。代码重构和优化:对现有代码进行审查,查找并消除重复代码、提取公共部分、优化性能瓶颈等,以提高代码质量和性能。增加注释和文档:为代码添加必要的注释和文档,说明每个函数或模块的作用、参数意义、返回值等信息,以便其他开发者能够更容易理解和使用代码。优化循环逻辑:当前的代码中有两个循环,可以考虑将其合并为一个,以提高效率并简化代码结构。使用Map优化答案检索:当前的代码中使用了List来存储学生的答案,但是通过索引来检索答案可能会导致错误。使用Map数据结构可以更快速、更可靠地获取答案。减少重复工作:在第一个循环中,已经检查了答案是否为null,并输出了相应的信息。在第二个循环中也有类似的检查,可以考虑在第一个循环中直接计算总分,并在第二个循环中只输出结果。
合理使用数据结构:确保数据结构的选择是合理的,以提高代码的可读性和性能。采用更清晰的命名和注释:确保变量名和函数名清晰易懂,同时添加适当的注释来解释代码的目的和逻辑。避免字符串比较异常处理:确保对异常情况进行适当的处理,例如学生ID找不到对应的姓名时应该如何处理。单一职责原则:确保每个函数或代码块只负责一项任务,遵循单一职责原则,以提高代码的可维护性和扩展性。
以上主要是对第三作业的最后议题的总结,主要是为这道题的思路模式提出了更清晰的想法,以便于提高代码的效率