首页 > 编程语言 >答题判题程序1~3总结

答题判题程序1~3总结

时间:2024-04-21 14:23:39浏览次数:25  
标签:总结 题目 String 答题 ArrayList 试卷 id 判题 public

一.前言

第一次作业知识点、题量、难度总结

1.第一次作业的主要内容为:

输入题目信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。

其中输入的信息主要为:题目数量,题目内容,答题信息,以"end"结束输入。

要求输出答题信息和判题信息。

2.主要涉及到的知识点:

(1)面向对象编程:代码中使用了类和对象的概念,通过定义类和创建对象来组织和管理代码。

(2)输入输出:使用 Scanner 类来处理用户输入,从控制台读取用户输入的题目和答案。

(3)正则表达式:通过简单的正则表达式来解析输入的题目和答案,从中提取题目编号、题目内容和标准答案。

(4)排序使用: Collections.sort() 方法来对题目列表进行排序,这里是按照题目编号进行升序排序。

(5)比较器:自定义了一个比较器用于对题目对象进行比较排序。

(6)控制流程:使用了条件语句(if)、循环语句(for)等控制流程语句来实现程序的逻辑。

(7)方法和参数:定义了多个方法,并使用参数来传递数据和调用方法。

3.题量和难度情况

第一次作业的题量并不多,难度也不高,代码行数在一百五十行左右。

第二次作业知识点、题量、难度总结

1.第二次作业的主要内容为:

设计实现答题程序,模拟一个小型的测试,在答题判题程序-1基础上增补或者修改内容。

要求输入题目信息、试卷信息和答题信息,根据输入题目信息中的标准答案判断答题的结果。

程序输入信息分三种,三种信息可能会打乱顺序混合输入。

输出内容为:试卷总分警示,答卷信息,判分信息,提示错误的试卷号

2.主要涉及到的知识点:

(1)类和对象:代码中定义了 Judge 类以及其成员变量和方法。类是面向对象编程的基本单位,用于封装数据和行为。

(2)集合:代码中使用了 ArrayList 来存储题目、试卷和答题卡等对象的列表。ArrayList 是 Java 中常用的动态数组实现,用于存储对象集合。

(3)循环:代码中使用了 for 循环来遍历试卷列表、题目列表以及学生答题列表等。

(4)条件语句:代码中使用了 if-else 条件语句来进行条件判断,例如判断试卷的总分是否为 100 分,以及判断学生的答案是否正确。

(5)方法调用和参数传递:代码中定义了方法,并通过调用这些方法来实现特定功能。方法可以接受参数,并根据参数执行相应的操作。

(6)字符串处理:代码中涉及了对字符串的处理,包括字符串的拼接和比较等操作。

(7)异常处理:代码中并没有显式地处理异常,但在某些情况下可能会引发异常,例如试卷不存在时给出提示信息。

(8)格式化输出:代码中使用了 System.out.printf 方法来格式化输出学生的得分情况。

3.题量和难度情况

题量相比于第一次作业有了很大的提升,难度也加大了许多,代码行数约为300行

第三次作业知识点、题量、难度总结

1.第三次作业的主要内容为:

设计实现答题程序,模拟一个小型的测试,以下粗体字显示的是在答题判题程序-2基础上增补或者修改的内容,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。

程序输入信息分五种,分别为:题目信息,试卷信息,答卷信息,学生信息,删除题目信息,信息可能会打乱顺序混合输入。

输出内容有:试卷总分警示,答卷信息,判分信息,被删除的题目提示信息,题目引用错误提示信息,格式错误提示信息,试卷号引用错误提示输出,学号引用错误提示信息。

2.主要涉及到的知识点:

(1)循环与条件判断:使用 for 循环和 if-else 条件判断语句对试题进行遍历和评分,并根据条件输出相应的信息。

(2)集合操作:使用 ArrayList 存储试题、答案、得分等信息,并通过集合操作对其进行遍历、查找和获取数据。

(3)对象与类的使用:涉及 Testpaper、Topic 和 Answerpaper 等自定义类的使用,通过对象调用其方法和获取属性。

(4)异常处理:在检查学生答案时,对可能出现的异常情况进行处理,如学生未回答、题目不存在等情况。

(5)字符串处理:对字符串进行拼接、比较和格式化输出,如拼接题目内容和学生答案,格式化输出学生姓名和得分等。(重点部分,要求熟练使用正则表达式)

(6)算术运算:对得分进行累加和计算总分。

(7)逻辑控制:根据题目的有效性和学生答案的正确性进行逻辑判断,决定是否给分并输出相应信息。

3.题量和难度情况

第三次作业的题量很多,难度提升很大,做题时间很长,代码行数约为500行。

二.设计与分析

第一次作业

1.

第一次作业最后一题设计思路:定义了三个类,分别为Topic,Testpaper,Answerpaper。Topic属性有题目的编号,内容,以及标准答案,Testpaper中有两个属性,一个是topiclist,用于存储试卷中的题目,另一个是

number属性,用于存储试卷中的题目数量,同时还定义了添加题目和给题目排序的方法。Answerpaper用于存储对应试卷,学生答案和判题结果,以及输出判题结果。整体过程为,main方法中先接收题目数量,然后利用

正则表达式将题目信息读取并添加到试卷中。添加完毕后根据题目数量决定是否读取答案信息。最后就是对试卷中的题目排序,判题,输出题目和学生答案,输出判题结果。

2.整体分析

功能完整性: 实现了试卷的创建、题目的录入、学生答案的输入、判题和结果展示等功能,系统可以完成基本的试卷管理任务。

封装性良好: 将试卷相关的数据和操作封装在了 Testpaper 类中,将答卷相关的数据和操作封装在了 Answerpaper 类中,这样做有助于提高代码的可维护性和可扩展性。

使用了集合类和排序功能: 使用了 LinkedList 来存储题目列表、答案列表和判题结果列表,并实现了根据题目编号排序的功能,展示了对 Java 集合类和排序算法的掌握。

3.具体代码分析如下

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main{
public static void main(String[]args){
Scanner input=new Scanner(System.in);
Answerpaper answerpaper=new Answerpaper();
int n=input.nextInt();//接收题目数量
input.nextLine();

    for(int i=0;i<n;i++){//读取题目编号,内容,答案并存储到试卷中
        String question=input.nextLine();
        Pattern pattern=Pattern.compile(":([^#]+)");//利用正则表达式读取冒号后,非#的内容
        Matcher matcher=pattern.matcher(question);
        String[] temp=new String[]{"0","0","0"};
    for (int j=0;j<3;j++){
        if (matcher.find()){
        String match = matcher.group(1).trim();
        temp[j] = match;
        }
    }
    answerpaper.addquestion(temp[0],temp[1],temp[2]);
}
    if(n!=0){//如果n不等于0,也就是说有题目,才会执行此步骤接收答案
    for(int i=0;i<1;i++){
        String answer=input.nextLine();
        Pattern pattern=Pattern.compile(":([^#]+)");
        Matcher matcher=pattern.matcher(answer);
        String[] temp=new String[n];
    for (int j=0;j<n&&matcher.find();j++){
        String match = matcher.group(1).trim();
        answerpaper.getAnswerlist().add(match);
    }
}
    }
    String end=input.nextLine();//用于接收end
    answerpaper.getTestpaper().sort();//对试卷中的题目进行排序
    answerpaper.judgequestion();//判断答案对错
    for(int i=0;i<n;i++){
        System.out.println(answerpaper.getTestpaper().getTopiclist().get(i).getContent()+"~"+answerpaper.getAnswerlist().get(i));
        //输出题目内容以及学生答案
    }
    answerpaper.showresult();//输出判题结果

}
}
class Topic{
private String id;//题目编号
private String content;//题目内容
private String standardAnswer;//标准答案

public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getContent() {
    return content;
}
public void setContent(String content) {
    this.content = content;
}
public String getStandardAnswer() {
    return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
    this.standardAnswer = standardAnswer;
}
public Topic(String id,String content,String standardAnswer){
    this.id=id;
    this.content=content;
    this.standardAnswer=standardAnswer;
}
public boolean judge(String answer){//判题
    if(answer.equals(this.standardAnswer))return true;
    else return false;
}

}
class Testpaper{
Scanner input=new Scanner(System.in);
private LinkedList topiclist=new LinkedList<>();//试卷中所含的题目列表
private int number=0;//试卷中的题目数量

public Testpaper(){
}
public int getNumber() {
    return number;
}
public void setNumber(int number) {
    this.number = number;
}
public LinkedList<Topic> getTopiclist() {
    return topiclist;
}
public void setTopiclist(LinkedList<Topic> topiclist) {
    this.topiclist = topiclist;
}

public void addtopic(String id,String content,String standardAnswer){//为试卷中的topiclist添加题目
    Topic topic=new Topic(id,content,standardAnswer);
    topiclist.add(topic);
    this.number++;
}

public void sort() {//使试卷中的题目根据题目编号的大小排序
Collections.sort(topiclist, new Comparator() {
@Override
public int compare(Topic t1, Topic t2) {
int id1 = Integer.parseInt(t1.getId());
int id2 = Integer.parseInt(t2.getId());
return Integer.compare(id1, id2);
}
});
}//使用了Java的Collections.sort方法,并传入了一个自定义的比较器来指定排序规则。比较器的作用是比较两个题目的编号大小,然后根据比较结果返回排序顺序。
}
class Answerpaper{
Scanner input=new Scanner(System.in);
private Testpaper testpaper=new Testpaper();//答卷所对应的试卷
private LinkedList answerlist=new LinkedList<>();//答案列表
private LinkedList judgelist=new LinkedList<>();//判题结果列表
public Answerpaper(){
}
public Testpaper getTestpaper() {
return testpaper;
}
public void setTestpaper(Testpaper testpaper) {
this.testpaper = testpaper;
}
public LinkedList getAnswerlist() {
return answerlist;
}
public void setAnswerlist(LinkedList answerlist) {
this.answerlist = answerlist;
}
public void addanswer(){
String answer=input.next();
answerlist.add(answer);
}
public void addquestion(String id,String content,String standardAnswer){
this.testpaper.addtopic(id,content,standardAnswer);
}
public void judgequestion(){//判题,并将判题结果存储到judgelist中
for(int i=0;i<testpaper.getNumber();i++){
judgelist.add(answerlist.get(i).equals(testpaper.getTopiclist().get(i).getStandardAnswer()));
}
}
public void showresult(){//输出所有判题结果
for(int i=0;i<testpaper.getNumber();i++){
if(i==testpaper.getNumber()-1){
System.out.print(judgelist.get(i));
break;
}
System.out.print(judgelist.get(i)+" ");
}
}
}

第二次作业

1.第二次作业最后一题设计思路:定义了三个类,分别为Topic,Testpaper,Answerpaper。Topic属性有题目的编号,内容,以及标准答案,与第一次作业无差别。Testpaper中有三个属性,一个是questionlist,用于存储试

卷中的题目,二是questionScorelist,用于存储每一题所对应的分数,第三个是id用于匹配答卷,与第一次作业相比较添加了试卷分数列表。Answerpaper中有答案列表和答卷编号,与第一次相比减少了部分功能。新增

Judge类将试卷,答卷,题目整合起来,便于判题,内含试卷总分警告方法,和判题方法。判题过程main中循环读取每一行信息,通过正则表达式来判断所读取的信息种类,创建对应的对象,添加至对应的列表中。最后通过

创建Judge对象输出警告和判题结果。

2.整体分析:代码功能主要包括以下几个部分:

判断试卷是否存在。
获取试卷的题目列表、分数列表和标准答案。
获取学生的答案列表。
判断学生的答案是否正确,计算总分。
输出每道题的得分情况和总分。

代码结构: 代码结构相对清晰,分为几个逻辑步骤,包括初始化、判断试卷是否存在、获取相关列表、计算分数和输出分数等。每个步骤的功能比较明确,便于理解和维护。

异常处理: 代码中已经对学生答案是否为空进行了处理,但是还可以进一步完善异常处理机制,考虑处理更多可能的异常情况,比如试卷和答案列表的长度不一致等情况。

输出格式化: 输出每道题的得分情况和总分时,使用了格式化的输出方法,但是还可以考虑添加更多的说明性文字,以提高输出结果的可读性。

命名和注释: 代码中使用了较为清晰的变量命名,并添加了一些注释来解释代码的逻辑和功能,但是还可以进一步完善命名和注释,以提高代码的可读性和可维护性。

算法复杂度: 代码在整体上没有明显的性能问题,但是可以考虑优化一些地方,比如使用更高效的数据结构或算法来提高代码的执行效率。

3.具体代码分析如下:

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

    ArrayList<Topic> topiclist=new ArrayList<>();//创建学生题目列表
    ArrayList<Testpaper> testpaperlist=new ArrayList<>();//创建试卷列表
    ArrayList<Answerpaper> answerpaperlist=new ArrayList<>();//创建答卷列表
    
    String in=input.nextLine();//输入数据
    
    while(!in.equals("end")){//循环输入,直到end结束
        if(in.startsWith("#N:")){//判断为题目信息
            String patternStr = "#N:(\\d+) #Q:(.*?) #A:(\\S+)";//正则表达式匹配题目内容
            Pattern pattern = Pattern.compile(patternStr);
            Matcher matcher = pattern.matcher(in);
            if (matcher.find()) {
                String id = matcher.group(1);
                String content = matcher.group(2);
                String standardAnswer= matcher.group(3);
                Topic topic=new Topic(id,content,standardAnswer);//创建题目对象
                topiclist.add(topic);//将题目添加到题目列表中
            }
        }
        if(in.startsWith("#T:")){//判断为试卷信息
                String patternStr = "#T:(.*)";//判断为试卷信息
                Pattern pattern = Pattern.compile(patternStr);//正则表达式匹配试卷内容
                Matcher matcher = pattern.matcher(in);
                if (matcher.find()) {
                    String data = matcher.group(1);
                    String[] segments = data.split("\\s+");
                    Testpaper testpaper=new Testpaper(segments[0]);//创建试卷对象
                    for (int i = 0; i < segments.length; i++) {
                        String segment = segments[i];
                        String[] parts = segment.split("-");
                        if (parts.length == 2) {
                                String key = parts[0];
                                String value = parts[1];
                            for(int j=0;j<topiclist.size();j++){
                                if(topiclist.get(j).getId().equals(key)){
                                    testpaper.getQuestionlist().add(topiclist.get(j));
                                    testpaper.getQuestionScorelist().add(Integer.parseInt(value));
                                }
                            }
                        }
                    }
                    testpaperlist.add(testpaper);//将试卷添加到试卷列表中
                }
        }
                if (in.startsWith("#S:")) {//判断为答卷信息
                    String patternStr = "#S:(\\d+)";//正则表达式匹配答卷内容
                    Pattern pattern = Pattern.compile(patternStr);
                    Matcher matcher = pattern.matcher(in);
                    if (matcher.find()) {  
                        String questionId = matcher.group(1);
                        Answerpaper answerpaper = new Answerpaper(questionId);//创建答卷对象
                        patternStr = "\\s+#A:(\\d+)"; //
                        Pattern answerPattern = Pattern.compile(patternStr);
                        Matcher answerMatcher = answerPattern.matcher(in);

                        if (answerMatcher.find()) {
                            answerpaper.getAnswerlist().add(answerMatcher.group(1));
                        }

                        while (answerMatcher.find()) {
                            answerpaper.getAnswerlist().add(answerMatcher.group(1));
                        }
                        answerpaperlist.add(answerpaper);//将答卷添加到答卷列表中
                    }
                }
        in=input.nextLine();
    }
    Judge judge=new Judge(topiclist,testpaperlist,answerpaperlist);//创建判断类
    judge.totalScoreWarning();//试卷总分警告
    
    int m=answerpaperlist.size()-testpaperlist.size();//判断试卷和答卷数量是否匹配
    
    for(int i=0;i<testpaperlist.size();i++){//输出判分结果
        judge.revisePaper(testpaperlist.get(i).getId(),0);
        if(m>0){judge.revisePaper(testpaperlist.get(i).getId(),m);m--;}
        if(m<0){judge.revisePaper(testpaperlist.get(i).getId(),m);m++;}
    }
}

}
class Topic{
private String id;//题目编号
private String content;//题目内容
private String standardAnswer;//题目标准答案

public Topic(String id,String content,String standardAnswer){
    this.id=id;
    this.content=content;
    this.standardAnswer=standardAnswer;
}

public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getContent() {
    return content;
}
public void setContent(String content) {
    this.content = content;
}
public String getStandardAnswer() {
    return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
    this.standardAnswer = standardAnswer;
}

public boolean judge(String answer){//判断答案是否正确
    if(answer.equals(this.standardAnswer))return true;
    else return false;
}

}
class Testpaper {
private String id;//试卷编号
private ArrayList questionlist = new ArrayList<>();//试卷所含题目列表
private ArrayList questionScorelist = new ArrayList<>();//每一题所对应的分数

public Testpaper(String id){
    this.id=id;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public ArrayList<Topic> getQuestionlist() {
    return questionlist;
}

public void setQuestionlist(ArrayList<Topic> questionlist) {
    this.questionlist = questionlist;
}

public ArrayList<Integer> getQuestionScorelist() {
    return questionScorelist;
}

public void setQuestionScorelist(ArrayList<Integer> questionScorelist) {
    this.questionScorelist = questionScorelist;
}

public ArrayList<String> getStandardAnswer(){//获得标准答案列表
    ArrayList<String> standardAnswer=new ArrayList<>();
    for(int i=0;i<questionlist.size();i++){
        standardAnswer.add(questionlist.get(i).getStandardAnswer());
    }
    return standardAnswer;
}

}
class Answerpaper {
private String id;//答卷编号
private ArrayList answerlist = new ArrayList<>();//答案列表
public Answerpaper(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ArrayList getAnswerlist() {
return answerlist;
}
public void setAnswerlist(ArrayList answerlist) {
this.answerlist = answerlist;
}
}
class Judge{//新增判断类,用于将题目答案和试卷联系起来
private ArrayList topiclist=new ArrayList<>();
private ArrayList testpaperlist=new ArrayList<>();
private ArrayList answerpaperlist=new ArrayList<>();

public Judge(ArrayList<Topic> topiclist,ArrayList<Testpaper> testpaperlist,ArrayList<Answerpaper> answerpaperlist){
    this.topiclist=topiclist;
    this.testpaperlist=testpaperlist;
    this.answerpaperlist=answerpaperlist;
}

public ArrayList<Topic> getTopiclist() {
    return topiclist;
}

public void setTopiclist(ArrayList<Topic> topiclist) {
    this.topiclist = topiclist;
}

public ArrayList<Testpaper> getTestpaperlist() {
    return testpaperlist;
}

public void setTestpaperlist(ArrayList<Testpaper> testpaperlist) {
    this.testpaperlist = testpaperlist;
}

public ArrayList<Answerpaper> getAnswerpaperlist() {
    return answerpaperlist;
}

public void setAnswerpaperlist(ArrayList<Answerpaper> answerpaperlist) {
    this.answerpaperlist = answerpaperlist;
}

public void totalScoreWarning(){//试卷总分警告
    for(int i=0;i<testpaperlist.size();i++){
        int sum=0;
        for(int j=0;j<testpaperlist.get(i).getQuestionScorelist().size();j++){
            sum+=testpaperlist.get(i).getQuestionScorelist().get(j);
        }
        if(sum!=100)System.out.println("alert: full score of test paper"+testpaperlist.get(i).getId()+" is not 100 points");
    }
}

public void revisePaper(String id,int m) {//根据id找试卷和答卷
Testpaper testpaper = null;
Answerpaper answerpaper = null;
int t=m;
for (int i = 0; i < testpaperlist.size(); i++) {//找试卷
Testpaper paper = testpaperlist.get(i);
if (paper.getId().equals(id)) {
if(t>=0){
testpaper = paper;
break;
}
else{
t++;
continue;
}
}
}

for (int i = 0; i <answerpaperlist.size(); i++) {//找答卷
    Answerpaper paper = answerpaperlist.get(i);
    if (paper.getId().equals(id)) {
        if(t<=0){
        answerpaper = paper;
        break;
        }
        else{
            t--;
            continue;
        }
    }
}
if(answerpaper==null){//判断试卷是否存在
    System.out.println("The test paper number does not exist");
    return;
}
ArrayList<Topic> questions = testpaper.getQuestionlist();//获取题目列表
ArrayList<Integer> questionScores = testpaper.getQuestionScorelist();//获取分数列表
ArrayList<String> studentAnswers = answerpaper.getAnswerlist();//获取学生答案
ArrayList<String> correctAnswers = testpaper.getStandardAnswer();//获取标准答案

int totalScore = 0;//计算总分
ArrayList<Integer> score=new ArrayList<>();//每一题的得分情况
for (int i = 0; i < questions.size(); i++) {
    if(i>=studentAnswers.size()){
        System.out.println("answer is null");//答案为空
        score.add(0);
    }
    else{//判分并统计过程
            String question = questions.get(i).getContent();
            int questionScore = questionScores.get(i);
            String studentAnswer = studentAnswers.get(i);
            String correctAnswer = correctAnswers.get(i);
            boolean isCorrect = studentAnswer.equals(correctAnswer);
            System.out.println(question+"~"+studentAnswer+"~"+isCorrect);
            if (isCorrect) {
                totalScore += questionScore; 
                score.add(questionScore);
            }
            else{
            score.add(0);
            }
        }
}

for(int i=0;i<score.size();i++){//输出最后的得分情况
    if(i==score.size()-1){
    System.out.printf("%d~",score.get(i));
        break;
    }
    System.out.printf("%d ",score.get(i));
}
System.out.println(totalScore);
}

}

第三次作业

1.第三次作业最后一题设计思路:大体上与第二次作业区别不大,主要讲不同的部分。首先新增学生类,便于添加存储学生的信息。然后程序涉及到删除题目信息,但为了方便输出错误提示,并没有删除题目,而是在题目中添

加了effective这一属性,默认为true,若题目被删除则改为false,题目无效。答卷类中新增学生学号studentid这一属性,还新增了answeidlist用于存储学生所答是试卷哪一题的答案。Judge类中的判题方式有很大改动,

第二次作业是根据id找试卷和答卷,这样做存在很多问题,因为试卷和答卷的数量不一定一样,也有可能不匹配,所以这次直接将答卷作为参数传入,根据答卷找试卷,修复了部分bug,同时也使代码更加易懂。最后是信息

读取的部分,为了筛选出错误信息并解决乱序输入带来的问题,第三次作业没有像前两次一样边读信息边添加,而是先将信息全部读取到inputlist中,再依次读入对应信息,读取完后将正确信息移除列表,最后输出剩下的错

误信息。

2.代码具体分析:

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main{
public static void main(String[]args){
Scanner input=new Scanner(System.in);
ArrayList studentlist=new ArrayList<>();//创建学生列表
ArrayList topiclist=new ArrayList<>();//创建题库
ArrayList testpaperlist=new ArrayList<>();//创建试卷列表
ArrayList answerpaperlist=new ArrayList<>();//创建答卷列表

    ArrayList<String> inputlist=new ArrayList<>();//存储读入的信息
    String in=input.nextLine();
    while(!in.equals("end")){//先将所有信息读入,便于后续处理避免乱序输入和错误输入
        inputlist.add(in);
        in=input.nextLine();
    }
    
    for(int k=0;k<inputlist.size();){//先读取题目信息,读取完毕后将其移除inputlist
        in=inputlist.get(k);
        if(in.matches("^#N:\\d+ #Q:(.+) #A:(.+)")){//利用十分严格的正则表达式匹配题目信息(这一步非常关键)
                String patternStr = "^#N:(\\d+) #Q:(.+) #A:(.+)";
                Pattern pattern = Pattern.compile(patternStr);
                Matcher matcher = pattern.matcher(in);
                if (matcher.find()) {
                    String id = matcher.group(1).trim();
                    String content = matcher.group(2).trim();
                    String standardAnswer= matcher.group(3).trim();
                    Topic topic=new Topic(id,content,standardAnswer);
                    topiclist.add(topic);//将读取好的题目添加至题目列表
                }
            inputlist.remove(k);//移除题目
        }
        else{
            k++;//使循环趋近于结束
        }
    }

    for(int k=0;k<inputlist.size();){//第二读取删除题目信息,读取完毕后将其移除inputlist
        in=inputlist.get(k);
        if(in.matches("#D:N-\\d+$")){//利用十分严格的正则表达式匹配删除题目信息(这一步非常关键)
                    String patternStr = "#D:N-(\\d+)";
                    Pattern pattern = Pattern.compile(patternStr);
                    Matcher matcher = pattern.matcher(in);
            if(matcher.find()){
                String deleteid=matcher.group(1).trim();
                for(int i=0;i<topiclist.size();i++){
                    if(topiclist.get(i).getId().equals(deleteid)){
                        topiclist.get(i).setEffective(false);
                        topiclist.get(i).setContent(null);
                        topiclist.get(i).setStandardAnswer(null);
                    }
                }
            }
            inputlist.remove(k);//删除完毕后将其移除
        }
        else{
            k++;//使循环趋近于结束
        }
    }
    
    for(int k=0;k<inputlist.size();){//第三读取试卷信息,读取完毕后将其移除inputlist
        in=inputlist.get(k);
        if(in.matches("^#T:(\\d+)( \\d+-\\d+)*$")){//利用十分严格的正则表达式匹配试卷信息(这一步非常关键)
                String patternStr = "^#T:(\\d+)( \\d+-\\d+)*$";
                Pattern pattern = Pattern.compile(patternStr);
                Matcher matcher = pattern.matcher(in);
                if(matcher.find()){
                Testpaper testpaper=new Testpaper(matcher.group(1).trim());
                String patStr= "(\\d+)-(\\d+)";
                Pattern pat=Pattern.compile(patStr);
                Matcher mat = pat.matcher(in);
                while (mat.find()) {
                                String key = mat.group(1).trim();
                                String value = mat.group(2).trim();
                                Boolean WhetherAddQuestion=false;
                            for(int j=0;j<topiclist.size();j++){
                                if(topiclist.get(j).getId().equals(key)){
                                    testpaper.getQuestionlist().add(topiclist.get(j));
                                    testpaper.getQuestionScorelist().add(Integer.parseInt(value));
                                    WhetherAddQuestion=true;
                                }
                            }
                            if(!WhetherAddQuestion){//无效的题目添加
                                testpaper.getQuestionlist().add(null);
                                testpaper.getQuestionScorelist().add(0);
                            }
                        }
                    testpaperlist.add(testpaper);//将testpaper添加到列表中
                    inputlist.remove(k);//移除信息
                }
        }
        else{
            k++;//使循环趋近于结束
        }
    }
    
    for(int k=0;k<inputlist.size();){//第四读取学生信息
        in=inputlist.get(k);
        if(in.matches("^#X:(\\w+ [^\\s-]+)?(-\\w+ [^\\s-]+)*$")) {//利用十分严格的正则表达式匹配学生信息(这一步非常关键)
            String patternStr = "#X:(.*)";
            Pattern pattern = Pattern.compile(patternStr);
            Matcher matcher = pattern.matcher(in);
            if (matcher.find()) {
                String data1 = matcher.group(1).trim();
                String[] segments1 = data1.split("-");
                for (int i = 0; i < segments1.length; i++) {
                    String segment = segments1[i];
                    String[] parts1 = segment.split("\\s+");
                    Student student=new Student(parts1[0],parts1[1]);
                    studentlist.add(student);//添加学生到列表中
                }
            }
            inputlist.remove(k);//移除信息
        }
        else{
            k++;//使循环趋近于结束
        }
    }
    
    
    for(int k=0;k<inputlist.size();){//最后读取学生答卷信息
        in=inputlist.get(k);
        if (in.matches("^#S:(\\d+) (\\S*)( #A:\\d+-(.*))*")) {//利用十分严格的正则表达式匹配答卷信息(这一步非常关键)
            String patternStr = "^#S:(\\d+) (\\S*)";
            Pattern pattern = Pattern.compile(patternStr);
            Matcher matcher = pattern.matcher(in);
            if (matcher.find()) {  
                String questionId = matcher.group(1).trim();
                String studentid=matcher.group(2).trim();
                Answerpaper answerpaper = new Answerpaper(questionId);
                answerpaper.setStudentid(studentid);
                patternStr = "#A:(\\d+)-(.*?)(?=#A:|$)";//匹配学生答案(重要)
                Pattern answerPattern = Pattern.compile(patternStr);
                Matcher answerMatcher = answerPattern.matcher(in);
                while (answerMatcher.find()) {
                    String answerid=answerMatcher.group(1).trim();
                    String answercontent=answerMatcher.group(2).trim();
                    answerpaper.getAnsweridlist().add(answerid);
                    answerpaper.getAnswerlist().add(answercontent);
                }
                answerpaperlist.add(answerpaper);//添加答卷到列表中
            }
            inputlist.remove(k);//移除信息
        }
        else{
            k++;//使使循环趋近于结束
        }
    }
    
    for(int i=0;i<inputlist.size();i++){//正确信息都移除后剩下的即为错误信息,将其输出
        System.out.println("wrong format:"+inputlist.get(i));
    }
    
    Judge judge=new Judge(topiclist,testpaperlist,answerpaperlist,studentlist);
    judge.totalScoreWarning();//试卷总分警告
    if(!answerpaperlist.isEmpty()){//确认答卷列表不为空
    for(int i=0;i<answerpaperlist.size();i++){
            judge.revisePaper(answerpaperlist.get(i));
        }
    }
}

}
class Student{
private String name;//学生姓名
private String id;//学生学号
public Student(String id,String name) {
this.id=id;
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
class Topic{
private String id;//题目编号
private String content;//题目内容
private String standardAnswer;//标准答案
private Boolean effective=true;//题目有效性
public Boolean getEffective() {
return effective;
}

public void setEffective(Boolean effective) {
    this.effective = effective;
}

public Topic(String id,String content,String standardAnswer){
    this.id=id;
    this.content=content;
    this.standardAnswer=standardAnswer;
}

public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getContent() {
    return content;
}
public void setContent(String content) {
    this.content = content;
}
public String getStandardAnswer() {
    return standardAnswer;
}
public void setStandardAnswer(String standardAnswer) {
    this.standardAnswer = standardAnswer;
}

public boolean judge(String answer){//判断答案是否正确
    if(answer.equals(this.standardAnswer))return true;
    else return false;
}

}
class Testpaper {
private String id;//试卷编号
private ArrayList questionlist = new ArrayList<>();//试卷所含题目列表
private ArrayList questionScorelist = new ArrayList<>();//每一题的分数

public Testpaper(String id){
    this.id=id;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public ArrayList<Topic> getQuestionlist() {
    return questionlist;
}

public void setQuestionlist(ArrayList<Topic> questionlist) {
    this.questionlist = questionlist;
}

public ArrayList<Integer> getQuestionScorelist() {
    return questionScorelist;
}

public void setQuestionScorelist(ArrayList<Integer> questionScorelist) {
    this.questionScorelist = questionScorelist;
}

}
class Answerpaper {
private String id;//答卷编号
private String studentid;//答卷学生学号
private ArrayList answerlist = new ArrayList<>();//答案列表
private ArrayList answeridlist=new ArrayList<>();//答题顺序号

public String getStudentid() {
    return studentid;
}
public void setStudentid(String studentid) {
    this.studentid = studentid;
}
public ArrayList<String> getAnsweridlist() {
    return answeridlist;
}
public void setAnsweridlist(ArrayList<String> answeridlist) {
    this.answeridlist = answeridlist;
}
public Answerpaper(String id) {
    this.id = id;
}
public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public ArrayList<String> getAnswerlist() {
    return answerlist;
}
public void setAnswerlist(ArrayList<String> answerlist) {
    this.answerlist = answerlist;
}

}
class Judge{
private ArrayList topiclist=new ArrayList<>();//题目列表
private ArrayList testpaperlist=new ArrayList<>();//试卷列表
private ArrayList answerpaperlist=new ArrayList<>();//答卷列表
private ArrayList studentlist=new ArrayList<>();//学生列表
public Judge(ArrayList topiclist,ArrayList testpaperlist,ArrayList answerpaperlist,ArrayList studentlist){
this.topiclist=topiclist;
this.testpaperlist=testpaperlist;
this.answerpaperlist=answerpaperlist;
this.studentlist=studentlist;
}
public ArrayList getStudentlist() {
return studentlist;
}

public void setStudentlist(ArrayList<Student> studentlist) {
    this.studentlist = studentlist;
}

public ArrayList<Topic> getTopiclist() {
    return topiclist;
}

public void setTopiclist(ArrayList<Topic> topiclist) {
    this.topiclist = topiclist;
}

public ArrayList<Testpaper> getTestpaperlist() {
    return testpaperlist;
}

public void setTestpaperlist(ArrayList<Testpaper> testpaperlist) {
    this.testpaperlist = testpaperlist;
}

public ArrayList<Answerpaper> getAnswerpaperlist() {
    return answerpaperlist;
}

public void setAnswerpaperlist(ArrayList<Answerpaper> answerpaperlist) {
    this.answerpaperlist = answerpaperlist;
}

public void totalScoreWarning(){//试卷总分警告
    for(int i=0;i<testpaperlist.size();i++){
        int sum=0;
        for(int j=0;j<testpaperlist.get(i).getQuestionScorelist().size();j++){
            sum+=testpaperlist.get(i).getQuestionScorelist().get(j);
        }
        if(sum!=100)System.out.println("alert: full score of test paper"+testpaperlist.get(i).getId()+" is not 100 points");
    }
}

public void revisePaper(Answerpaper answerpaper) {//改试卷
Testpaper testpaper = null;
for (int i = 0; i < testpaperlist.size(); i++) {//根据答卷找对应的试卷
Testpaper paper = testpaperlist.get(i);
if (paper.getId().equals(answerpaper.getId())) {
testpaper = paper;
break;
}
}
if(testpaper==null){//若未找到则输出警告
System.out.println("The test paper number does not exist");
return;
}

ArrayList<Topic> questions = testpaper.getQuestionlist();//获取题目
ArrayList<Integer> questionScores = testpaper.getQuestionScorelist();//获取分数

int totalScore = 0;
ArrayList<Integer> score=new ArrayList<>();

for (int i = 0; i < questions.size(); i++) {
    if(questions.get(i)==null){//判断试卷所添加的题目是否存在
        Boolean findanswer=false;//判断是否出现多种错误
        for(int j=0;j<answerpaper.getAnsweridlist().size();j++){
            if(Integer.parseInt(answerpaper.getAnsweridlist().get(j))==(i+1)){
                findanswer=true;
                break;
            }
        }
        if(findanswer){//根据优先级输出警告
            System.out.println("non-existent question~0");
            score.add(0);
        }
        else {
            System.out.println("answer is null");
            score.add(0);
        }
    }
    else{
            Boolean findanswer1=false;//确认题目添加无误后判断答案是否为空
            for(int j=0;j<answerpaper.getAnsweridlist().size();j++){
                if(Integer.parseInt(answerpaper.getAnsweridlist().get(j))==(i+1)){
                    findanswer1=true;
                    break;
                }
            }
            if(!findanswer1){
                System.out.println("answer is null");
                score.add(0);
            }
            else{
                if(questions.get(i).getEffective()){//判断题目的有效性
                        String question = questions.get(i).getContent();
                        int questionScore = questionScores.get(i);
                    
                        String studentAnswer=null;
                        for(int j=0;j<answerpaper.getAnsweridlist().size();j++){
                            if(Integer.parseInt(answerpaper.getAnsweridlist().get(j))==(i+1)){
                                studentAnswer=answerpaper.getAnswerlist().get(j);
                            }
                        }
                            
                        boolean isCorrect = studentAnswer.equals(questions.get(i).getStandardAnswer());
                        System.out.println(question+"~"+studentAnswer+"~"+isCorrect);
                        if (isCorrect) {
                            totalScore += questionScore; 
                            score.add(questionScore);
                        }
                        else{
                        score.add(0);
                        }
                    }
                else{
                System.out.println("the question "+questions.get(i).getId()+" invalid~0");//输出题目无效的警告
                    score.add(0);
                }
            }
    }
}

System.out.print(answerpaper.getStudentid()+" ");//输出学生信息
Boolean found=false;
for(int i=0;i<studentlist.size();i++){
    if(studentlist.get(i).getId().equals(answerpaper.getStudentid())){
        System.out.print(studentlist.get(i).getName()+": ");
        found=true;
        break;
    }
}
if(!found){
    System.out.println("not found");//未找到对应学生
}
else{//输出各题得分情况和总分
for(int i=0;i<score.size();i++){
    if(i==score.size()-1){
    System.out.printf("%d",score.get(i));
        break;
    }
    System.out.printf("%d ",score.get(i));
}
    System.out.println("~"+totalScore);
}
}

}

三.踩坑心得

主要在第三次作业最后一题上:

1.未考虑到题目,试卷,答卷列表为空的情况,导致单信息输入有问题。

2.未考虑信息乱序输入的情况。如先输入试卷信息,再输入题目信息

3.未考虑空字符情况

4.正则表达式不够严格,要认真读题,确保正则表达式的正确性

5.改了多次正则表达式,空白卷一直过不去,最后发现是自身方法的问题,导致遗漏了答卷。

以上是我踩过的坑,修改完后

四.改进建议

1.第一次作业改进建议

(1)封装输入逻辑:在 Answerpaper 类中,每次添加答案时都创建了一个新的 Scanner 对象,这样会造成资源的浪费。推荐将 Scanner 对象作为类的成员变量,并在构造函数中初始化,这样可以避免重复创建对象。

(2)错误处理:在 addanswer 方法中,应该添加对输入的错误情况的处理,比如输入不合法的答案格式等,以提高程序的健壮性。

(3)输入验证:在 addquestion 方法中,应该对输入的题目信息进行验证,确保输入的内容合法。

(4)异常处理:在 judgequestion 方法中,应该处理可能发生的下标越界异常,确保程序的稳定性。

(5)命名规范:变量和方法命名应该符合命名规范,清晰地表达其用途,提高代码的可读性。

(6)方法拆分:judgequestion 方法的功能比较复杂,建议将其拆分成更小的方法,每个方法只负责完成一个简单的任务,提高代码的可维护性。

(7)注释添加:适当添加注释,解释代码的功能、参数含义以及实现逻辑,有助于他人理解和维护代码。

(8)异常抛出:在可能引发异常的地方,可以考虑抛出合适的异常,而不是简单地忽略或处理掉,这样可以提高代码的健壮性。

2.第二次作业改进建议

(1)不可变性:考虑将类设计成不可变类(immutable),即去掉 setId、setQuestionlist、setQuestionScorelist 方法,并在构造函数中初始化所有属性。

(2)使用泛型:考虑使用泛型来定义题目列表和分数列表,以增加代码的灵活性和通用性。

(3)异常处理:在添加题目和分数时,可以添加一些异常处理逻辑,比如检查传入的参数是否为空或者长度是否一致。

(4)增加注释:在方法和属性上增加适当的注释,解释其用途和功能,有助于其他人理解和维护代码。

(5)考虑试卷的其他属性:如果试卷还有其他属性,比如总分数、考试时间等,可以考虑在类中添加对应的属性和方法。

(6)考虑答卷的其他属性:如果答卷还有其他属性,比如答卷提交时间、得分情况等,可以考虑在类中添加对应的属性和方法。

(7)简化代码:在 totalScoreWarning 方法中,可以使用增强型 for 循环来更简洁地实现。

(8)变量名可读性:变量名 t 在代码中使用了两次,但是它的含义在不同的上下文中是不同的。建议使用更具描述性的变量名来提高代码的可读性。

(9)代码重构:可以考虑将评分逻辑提取为一个单独的方法,以提高代码的可重用性和可维护性。

(10)输出格式:在输出得分情况时,可以考虑使用更加清晰的格式,使得结果更易读。

3.第三次作业改进建议

(1)使用接口或抽象类来表示题目、试卷和答卷,这样可以更好地实现多态性,让代码更加灵活。

(2)可以考虑使用Map而不是ArrayList来存储题目、试卷、答卷和学生,这样可以更方便地通过键值对进行访问和管理。

(3)totalScoreWarning方法中,建议使用增强for循环来遍历列表,这样代码会更简洁易读。

(4)在构造方法中,可以直接使用addAll方法将参数列表中的元素添加到类的成员变量中,而不需要逐个赋值。

(5)在输出学生信息时,可以直接使用Student对象的getName方法,而不需要再次遍历学生列表查找。

(6)在输出题目得分和总分时,可以使用StringJoiner来拼接字符串,使代码更加优雅。

(7)在遍历 inputlist 进行题目信息的读取时,直接对 inputlist 进行了元素的移除,这可能会导致遍历时的索引混乱。为了避免这种情况,可以将需要移除的元素的索引先存储起来,然后再统一移除。

五.总结

根据三次题目集,我主要学到了下面这些概念

1.模块化设计: 代码被分成了几个小块,每个块都负责一个特定的任务。这样的设计使得代码更易于理解、测试和维护。比如,将检查学生是否存在的逻辑封装成一个独立的方法,提高了代码的复用性。

2.异常处理: 在程序中,我们要考虑可能出现的异常情况,并做出相应的处理。比如,在查找学生是否存在时,如果找不到对应的学生,可以抛出一个异常或者返回一个特殊的值,而不是简单地打印一条消息。

3.代码复用: 将相似的功能封装成方法或者类,可以提高代码的复用性和可维护性。比如,在检查学生是否存在的逻辑中,我们将其封装成一个独立的方法,在需要时可以重复使用。

4.可读性和注释: 代码应该易于理解,包括给变量和方法起一个有意义的名字,添加注释来解释代码的作用和逻辑。这样可以让其他人更容易理解你的代码,也方便自己日后的维护和修改。

5.健壮性: 良好的异常处理和边界条件检查可以提高代码的健壮性,使其能够应对各种异常情况,而不是在遇到问题时崩溃或者产生不可预料的行为。

标签:总结,题目,String,答题,ArrayList,试卷,id,判题,public
From: https://www.cnblogs.com/lch1873316779/p/18147750

相关文章

  • linux shell 编程学习总结
    1文件和数组1.1读文件并将文件内容保存到数组,遍历数组src.f文件内容./src/xxx_1.md./src/xxx_2.md./src/xxx_3.md./src/xxx_4.md./src/xxx_5.mdrun.sh#!/bin/bash###readflisttoarraysrc_array=()whilereadline;dosrc_array+=("$line")done<$1##......
  • 三次答题判题程序练习让你入门Java。
    (1)前言本阶段三次题目集涵盖了从基础编程概念到较复杂算法设计等多个知识点。题量适中,难度呈梯度上升,从简单的数据结构与算法实现到复杂的问题求解,逐步挑战学生的编程能力。第一次题目集主要考察基本语法、数据类型和简单的控制结构;第二次题目集则增加了数组、链表等数据结构的应......
  • 题目集1-3总结
    前言设计与分析踩坑心得踩坑心得改进建议总结前言知识点每次题目集在小题上都能给出新的知识去让我们学习,包括类的构造,类的引用,数组的基本运用,对象的构造,更包括对属性状态的应用,尽管以我们现在的水平还无法真正理解到属性的状态对程序乃至工程整体的作......
  • 对前三周pta总结
    在进入总结之前,先讲讲我在学习过程中的曲折的心路历程:在刚开始学习java时,我觉得java与我们上学期接触的c语言(在语法上)没有什么差别,甚至在刚用java写一些简单题目时(数学题),感觉需要打非常多的字母,就例如输入这方面,c语言可能只需要scanf一下,但java却要先import一下,再......(不过多赘述......
  • Redis介绍、使用、数据结构和集群模式总结
    Redis(RemoteDictionaryServer)是一个开源的,基于内存的数据结构存储系统,它支持多种数据结构,如字符串(String)、列表(List)、集合(Set)、有序集合(SortedSet)、散列(Hash)等。Redis不仅可以用作数据库、缓存和消息代理,还可以通过复制、持久化、高可用性和分区提供强大的数据保障。以下是关于......
  • nchu-oop训练集1~3总结
    一、前言Java学习已经有一个多月了,虽然还是有些困难,但已不像初学C语言时那般吃力,Java是一门非常强大且有趣的编程语言。我喜欢Java的面向对象的特性,它让我可以更好地组织和管理我的代码。另外,Java的跨平台性也让我感到很方便,我可以在不同的操作系统上运行我的程序。这三次题目集......
  • PTA三次题目集总结性Blog
    (1)前言1.第一次题目集知识点主要涉及类的设计和实现、构造方法的使用、成员变量和访问器/修改器的定义、方法的重写(toString方法)、对象的创建和调用方法、控制台输入和输出的使用、浮点数的格式化输出等,题量比较适中,难度也比较适中,要求实现的功能较为基础,但需要一定的类设计和方......
  • 2024团体程序设计天梯赛——赛后总结
    历年天梯赛成绩2021年125分2022年123分2023年191分21年大一的时候因为刚开始学算法,学的很认真拿到了125分,虽然不是很高,但那年的题目很难,对我来说很满意了。22年大二,松懈了这一年,这一年题目很简单,成绩却下降了2分。现在想想很惭愧。23年大三,从开学到现在一直在不间断的刷题,又......
  • [ABC350] 赛后总结
    [ABC350]赛后总结AK之。A模拟//Problem:A-PastABCs//Contest:AtCoder-AtCoderBeginnerContest350//Author:Moyou//Copyright(c)2024MoyouAllrightsreserved.//Date:2024-04-2020:00:23#include<algorithm>#include<cstring>#incl......
  • Random 项目总结 -07 截取当前程序图片
    [DllImport("gdi32.dll",CharSet=CharSet.Auto,SetLastError=true,ExactSpelling=true)]publicstaticexternintBitBlt(HandleRefhDC,intx,inty,intnWidth,intnHeight,HandleRefhSrcDC,intxSrc,intySrc,intdwRop);p......