第一次blog
一.前言
1.前三次题目集的知识点:
(1)利用面对对象编程原理根据题目给的信息以及题目的复杂程度建立对应的类以及在类里加入方法。
(2)使用Java自带的类库运用Scanner类中的方法、regex.Matcher类中的方法、regex.Pattern类中的方法等。
(3)正则表达式的利用,利用正则表达式对题目给出的输入内容经行判断,输出对应结果或把输入内容分离加入到自己创建的类中。
(4)用了循环语句、条件语句等语句来控制程序的逻辑性。
(5)对异常情况的处理,把题目输入的大块字符串分割成一段一段的字符串进行逐个处理,判断出异常情况进行输出。
(6)按照题目要求输出相关结果,判断每道题的正误情况对题目进行批改、计算每张卷子的总分,判断每张卷子的总分是否等于一百等类似的格式输出正确结果。
(7)格式化输出有关结果,在过程中使用了System.out.println等方法来格式化输出学生的得分情况以及每道题的正确情况。
2.题量
(1)第一次大作业:题量较少,易于做完。
(2)第二次大作业:题量中等,需要一定时间。
(3)第三次大作业:题量较多,需要花费大量时间。
3.难度
(1)第一次大作业:难度较小,花费时间不长,较为轻松。
(2)第二次大作业:难度上升,花费时间增长,实现代码时较为费力。
(3)第三次大作业:难度较高,花费时间进一步增长,需要理清思路,设计好类之间的调用关系再实现代码。
二.设计与分析
1.第一次大作业
(1)设计与分析:
本次大作业设计了题目(topic)类,试卷(exam)类,答案(answer)类三个类。题目类用来存储题目所具备的属性编号,内容,标准答案,以及定义了get,set方法来获取和修改这些变量。试卷类用来存储试卷的编号,题目等信息,在试卷类里也定义了get,set方法,还定义了一个判断题目是否正确的方法,接受一个题目的答案,对应上题目的标准答案判断是否相等,以此批改试题。答案类除了上述内容还加入了保存试题判断结果的动态数组,用来存储批改结果便于输出。对应代码如下代码块:
`import java.util.Scanner;
import java.util.ArrayList;
class Topic
{
private int topicID;
private String topicContent;
private String standardAnswer;
public Topic(int topicID,String topicContent,String standardAnswer)
{
this.topicID=topicID;
this.topicContent=topicContent;
this.standardAnswer=standardAnswer;
}
public Topic()
{}
public int getTopicID()
{
return topicID;
}
public String getTopicContent()
{
return topicContent;
}
public String getStandardAnswer()
{
return standardAnswer;
}
public boolean judgeTopic1(String answer)
{
if(answer.equals(standardAnswer))
return true;
else
return false;
}
}
class Exam
{
private ArrayList
private int topicNumber;
public Exam(ArrayList
{
this.topics=topics;
this.topicNumber=topicNumber;
}
public Exam()
{}
public ArrayList
{
return topics;
}
public int getTopicNumber()
{
return topicNumber;
}
public void sortTopics()
{
for(int i=0;i<topicNumber-1;i++)
for(int j=0;j<topicNumber-i-1;j++)
if(topics.get(j).getTopicID()>topics.get(j+1).getTopicID())
{
Topic topic=new Topic();
topic=topics.get(j);
topics.set(j,topics.get(j+1));
topics.set(j+1,topic);
}
}
public boolean judgeTopic2(int num,String answer)
{
sortTopics();
return topics.get(num-1).getStandardAnswer().equals(answer);
}
}
class Answer
{
private Exam exam=new Exam();
private ArrayList
private ArrayList
public Answer(Exam exam,ArrayList
{
this.exam=exam;
this.answers=answers;
}
public boolean judgeTopic3(int num)
{
return exam.getTopics().get(num-1).getStandardAnswer().equals(answers.get(num-1));
}
public void printResult(int num)
{
exam.sortTopics();
System.out.println(exam.getTopics().get(num-1).getTopicContent()+"~"+answers.get(num-1));
}
public void saveAnswer(int num, String answer)
{
answers.set(num-1,answer);
}
}
public class Main
{
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
int topicNumber=input.nextInt();
ArrayList
input.nextLine();
for(int i=0;i<topicNumber;i++)
{
String line=input.nextLine();
int topicID=Integer.parseInt(line.substring(line.indexOf("#N:")+3,line.indexOf("#Q:")).trim());
String topicContent=line.substring(line.indexOf("#Q:")+3,line.indexOf("#A:")).trim();
String standardAnswer=line.substring(line.indexOf("#A:")+3).trim();
topics.add(new Topic(topicID,topicContent,standardAnswer));
}
Exam exam=new Exam(topics,topicNumber);
exam.sortTopics();
ArrayList
String[] answersString=new String[topicNumber];
for(int i=0;i<topicNumber;i++)
{
answersString[i]=input.next();
answers.add(answersString[i].replaceAll("#A:",""));
}
Answer answer=new Answer(exam,answers);
for(int i=0;i<topicNumber;i++)
answer.printResult(i+1);
for(int i=0;i<topicNumber-1;i++)
System.out.print(answer.judgeTopic3(i+1)+" ");
System.out.print(answer.judgeTopic3(topicNumber));
}
}`
(2)踩坑心得:
最开始提交发现全为格式错误,仔细检查后发现输出最后一个结果时不用加空格,修改代码使输出循环n-1次,第n次输入没空格的结果。修改后全对。
(3)改进建议:
可以加入正则表达式判断输入的字符串是否符合正确格式,可以简化主函数,将输出结果的相应代码写入试卷类中使主函数不显得累赘。
2.第二次大作业
(1)设计与分析:
本次大作业设计了题目(topic)类,试卷(exam)类,答案(answer),答卷类(answerlist)类四个个类。题目类用来存储题目所具备的属性编号,内容,标准答案,以及定义了get,set方法来获取和修改这些变量。试卷类用来存储试卷的编号,题目等信息,在试卷类里也定义了get,set方法,还定义了一个判断题目是否正确的方法,接受一个题目的答案,对应上题目的标准答案判断是否相等,以此批改试题。答案类除了上述内容还加入了保存试题判断结果的动态数组,用来存储批改结果便于输出。答卷类将试卷所有的题目加入其中,并且把答案列表加入其中,在答案类中定义了方法使对应答案与试题一一对应并且输出对应结果。对应代码如下代码块:
`import java.util.Scanner;
import java.util.ArrayList;
import java.util.HashMap;
class Topic
{
private int topicID;
private String topicContent;
private String standardAnswer;
public Topic(int topicID,String topicContent,String standardAnswer)
{
this.topicID=topicID;
this.topicContent=topicContent;
this.standardAnswer=standardAnswer;
}
public Topic()
{}
public int getTopicID()
{
return topicID;
}
public String getTopicContent()
{
return topicContent;
}
public String getStandardAnswer()
{
return standardAnswer;
}
public boolean judgeTopic1(String answer)
{
if(answer.equals(standardAnswer))
return true;
else
return false;
}
}
class Answer
{
private int answerID;
private Exam exam=new Exam();
private ArrayList
public Answer(int answerID,ArrayList
{
this.answerID=answerID;
this.answers=answers;
}
public void setExam(Exam exam)
{
this.exam=exam;
}
public boolean judgeTopic3(int num)
{
return exam.getTopics().get(num-1).getStandardAnswer().equals(answers.get(num-1));
}
public void printResult(int num)
{
exam.sortTopics();
System.out.println(exam.getTopics().get(num-1).getTopicContent()+""+answers.get(num-1)+""+exam.judgeTopic2(num-1));
}
/*public void printPoint(int num)
{
exam.sortTopics();
System.out.println(exam.)
}
*/
}
class Exam
{
private int examID;
private HashMap<Integer,Integer>topicPoints;
public Exam(int examID,HashMap<Integer,Integer>topicPoints)
{
this.examID=examID;
this.topicPoints=topicPoints;
}
public Exam()
{}
public int getExamID()
{
return examID;
}
public ArrayList
{
}
public void sortTopics()
{
ArrayList<Integer>topicIDs=new ArrayList<>(topicPoints.keySet());
ArrayList<Topic>Topics=new ArrayList<>();
for(int x:topicIDs)
{
Topics.add()
}
int topicNumber=topics.size();
for(int i=0;i<topicNumber-1;i++)
for(int j=0;j<topicNumber-i-1;j++)
if(topics.get(j).getTopicID()>topics.get(j+1).getTopicID())
{
Topic topic=new Topic();
topic=topics.get(j);
topics.set(j,topics.get(j+1));
topics.set(j+1,topic);
}
HashMap<Integer,Integer>tempMap=new HashMap<>(topicPoints);
topicPoints.clear();
for(Integer key:topics)
map.put(key,tempMap.get(key));
}
public boolean judgeTopic2(int num,String answer)
{
sortTopics();
ArrayList<Integer>topics=new ArrayList<>(topicPoints.keySet());
return topics.get(num-1).getStandardAnswer().equals(answer);
}
}
public class Main
{
public static void main(String[] args)
{
int topicNumber=0;
Scanner input=new Scanner(System.in);
ArrayList
ArrayList
ArrayList
while(!(String line=input.nextLine()).equals("end"))
{
if(line.startsWith("#N:"))
{
topicNumber++;
int topicID=Integer.parseInt(line.substring(line.indexOf("#N:")+3,line.indexOf("#Q:")).trim());
String topicContent=line.substring(line.indexOf("#Q:")+3,line.indexOf("#A:")).trim();
String standardAnswer=line.substring(line.indexOf("#A:")+3).trim();
topics.add(new Topic(topicID,topicContent,standardAnswer));
}
if(line.startsWith("#T:"))
{
ArrayList
HashMap<Integer,Integer>topicPoints=new HashMap<>();
int sumPoint=0;
for(int i=1;;i++)
{
String part=input.next();
if(partnull)
break;
if(i1)
{
int examID=Integer.parseInt(part.substring(line.indexOf("#T:")+3));
}
else
{
topicPoints.put(Integer.parseInt(part.substring(0,line.indexOf("-"))),Integer.parseInt(part.substring(line.indexOf("-")+1)));
sumPoint+=Integer.parseInt(part.substring(line.indexOf("-")+1));
}
}
exams.add(new Exam(examID,topicPoints));
if(sumPoint!=100)
System.out.println("alert: full score of test paper"+examID+" is not 100 points");
}
if(line.startsWith("#S:"))
{
ArrayList
for(int i=1;;i++)
{
String part=input.next();
if(partnull)
break;
if(i1)
{
int answerID=Integer.parseInt(part.substring(line.indexOf("#S:")+3));
}
else
{
answers.add(part.replaceAll("#A:",""));
}
}
answers.add(new Answer(answerID,answersString));
}
}
for(int i=0;i<topicNumber-1;i++)
for(int j=0;j<topicNumber-i-1;j++)
if(topics.get(j).getTopicID()>topics.get(j+1).getTopicID())
{
Topic topic=new Topic();
topic=topics.get(j);
topics.set(j,topics.get(j+1));
topics.set(j+1,topic);
}
for(Answer answer:answers)
{
for(Exam)
for(int i=0;i<topicNumber;i++)
answer.printResult(i+1);
}
}
}
`
(2)踩坑心得:
最开始类之间的调用关系没有使用好,导致出现多种编译错误,后面改正使得调用关系正确,并且改进了答卷类判断试题是否正确的相关方法,使得答卷类的层次以及与其他类之间的调用关系更加清晰,最终获得更高的分数。
(3)改进建议:
试卷类中的判断试题的方法可以将循环嵌套修改为多个循环,减少嵌套层数,使后面代码修改时不会太难并且可复用度高。主函数还是第一次大作业的问题,可以加入一个judgement类判断输入的格式是否符合要求,将每行都使用该类的判断格式方法,可以减少主函数的代码量,减少复杂性。
3.第三次大作业
(1)设计与分析
本次大作业设计了题目(topic)类,试卷(exam)类,答案(answer)类,判断(judgeformat),学生(student)五个个类。题目类用来存储题目所具备的属性编号,内容,标准答案,以及定义了get,set方法来获取和修改这些变量。试卷类用来存储试卷的编号,题目等信息,在试卷类里也定义了get,set方法,还定义了一个判断题目是否正确的方法,接受一个题目的答案,对应上题目的标准答案判断是否相等,以此批改试题。判断类定义一个方法接收一个字符串,判断是否与题目给的格式相同,若是返回一个布尔值。新增一个学生类,内含学生的学号和名字,在答案类中根据学生的学号对应学生的姓名,用定义的get方法获得学生的各种信息。答案类除了上述内容还加入了保存试题判断结果的动态数组,用来存储批改结果便于输出。对应代码如下代码块:
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Student
{
private String studentID;
private String name;
public Student(String studentID,String name)
{
this.studentID=studentID;
this.name=name;
}
public Student()
{}
public String getStudentID()
{
return studentID;
}
public String getName()
{
return name;
}
}
class Topic
{
private boolean exist;
private int topicID;
private String topicContent;
private String standardAnswer;
public Topic(int topicID,String topicContent,String standardAnswer)
{
exist=true;
this.topicID=topicID;
this.topicContent=topicContent;
this.standardAnswer=standardAnswer;
}
public Topic()
{}
public boolean getExist()
{
return exist;
}
public int getTopicID()
{
return topicID;
}
public String getTopicContent()
{
return topicContent;
}
public String getStandardAnswer()
{
return standardAnswer;
}
public void deleteTopic()
{
exist=false;
}
}
class Answer
{
private int answerID;
private String studentID;
private Student student;
private Exam exam;
private ArrayList
private ArrayList
private ArrayList
public Answer(int answerID,String studentID,ArrayList
{
this.answerID=answerID;
this.studentID=studentID;
this.answerIDList=answerIDList;
this.answerList=answerList;
student=new Student();
exam=new Exam();
topicPointList=new ArrayList<>();
}
public void setStudent(ArrayList
{
for(Student student1:students)
{
if(student1.getStudentID().equals(studentID))
{
this.student=student1;
break;
}
this.student=new Student();
}
}
public boolean setExam(ArrayList
{
for(Exam exam1:exams)
{
if(exam1.getExamID()answerID)
this.exam=exam1;
}
if(exam.getExamID()0)
{
System.out.println("The test paper number does not exist");
return false;
}
return true;
}
public void correctExam()
{
int totalScore=0;
int a=0;//a记录当前题目遍历数以对应题目分数
boolean sameNumber;
sameNumber=exam.getTopics().size()answerIDList.size();
for(Topic topic:exam.getTopics())
{
if(topic.getTopicID()0)
{
System.out.println("non-existent question~0");
topicPointList.add(0);
}
else
{
int i;
boolean answerExist=false;
for(i=0;i<answerIDList.size();i++)
if(a+1answerIDList.get(i))
{
answerExist=true;
break;
}
if(!answerExist)
{
System.out.println("answer is null");
topicPointList.add(0);
continue;
}
if(topic.getExist())
{
if(topic.getStandardAnswer().equals(answerList.get(i)))
{
topicPointList.add(exam.getPoints().get(a));
totalScore+=exam.getPoints().get(a);
}
else
topicPointList.add(0);
System.out.println(topic.getTopicContent()+""+answerList.get(i)+""+topic.getStandardAnswer().equals(answerList.get(i)));
}
else
{
topicPointList.add(0);
if(!sameNumber)
System.out.println("answer is null");
else
System.out.println("the question "+topic.getTopicID()+" invalid~0");
}
}
a++;
}
if(student.getStudentID()null)
System.out.println(studentID+" not found");
else
{
System.out.print(student.getStudentID()+" "+student.getName()+"😊;
for(int point:topicPointList)
System.out.print(" "+point);
System.out.println("~"+totalScore);
}
}
}
class Exam
{
private int examID;
private ArrayList
private ArrayList
private ArrayList
public Exam(int examID,ArrayList
{
this.examID=examID;
this.topicIDs=topicIDs;
topics=new ArrayList<>();
this.points=points;
}
public Exam()
{}
public int getExamID()
{
return examID;
}
public ArrayList
{
return points;
}
public void chooseTopics(ArrayList
{
for(int topicID:this.topicIDs)
{
boolean haveTopic=false;
for(Topic topic:topics)
if(topic.getTopicID()topicID)
{
this.topics.add(topic);
haveTopic=true;
}
if(!haveTopic)
this.topics.add(new Topic());
}
}
public ArrayList
{
return topics;
}
public void judgePoint()
{
int sum=0;
for(int point:points)
sum+=point;
if(sum!=100)
System.out.println("alert: full score of test paper"+examID+" is not 100 points");
}
}
class JudgeFormat
{
private String line;
public JudgeFormat(String line)
{
this.line=line;
}
public boolean judgement()
{
if(line.matches("^#N:\d+ #Q:.* #A:.$"))
return true;
else
if(line.matches("^#T:\d+( (\d+-\d+))$"))
return true;
else
if(line.matches("^#S:\d+ .( #A:\d+-\.)$"))
return true;
else
if(line.matches("^#X:(. .-).* .$"))
return true;
else
return line.matches("^#D:N-\d+$");
}
}
public class Main
{
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
ArrayList
ArrayList
ArrayList
ArrayList
ArrayList
while(true)
{
String line=input.nextLine();
if(line.equals("end"))
break;
else
{
JudgeFormat judge=new JudgeFormat(line);
if(judge.judgement())
{
if(line.startsWith("#N:"))
{
int topicID=Integer.parseInt(line.substring(line.indexOf("#N:")+3,line.indexOf("#Q:")).trim());
String topicContent=line.substring(line.indexOf("#Q:")+3,line.indexOf("#A:")).trim();
String standardAnswer=line.substring(line.indexOf("#A:")+3).trim();
topics.add(new Topic(topicID,topicContent,standardAnswer));
}
if(line.startsWith("#T:"))
{
ArrayList
ArrayList
int examID=0;
Pattern pattern1=Pattern.compile("^#T:(\d+)( \d+-\d+)
Matcher matcher1=pattern1.matcher(line);
if(matcher1.find())
{
examID=Integer.parseInt(matcher1.group(1).trim());
Pattern pattern2=Pattern.compile("(\d+)-(\d+)");
Matcher matcher2=pattern2.matcher(line);
while(matcher2.find())
{
int topicID=Integer.parseInt(matcher2.group(1).trim());
int point=Integer.parseInt(matcher2.group(2).trim());
topicIDs.add(topicID);
points.add(point);
}
}
exams.add(new Exam(examID,topicIDs,points));
}
if(line.startsWith("#S:"))
{
ArrayList
ArrayList
int answerID=0;
String studentID=null;
Pattern pattern1=Pattern.compile("^#S:(\d+) (\S+)");
Matcher matcher1=pattern1.matcher(line);
if(matcher1.find())
{
answerID=Integer.parseInt(matcher1.group(1).trim());
studentID=matcher1.group(2).trim();
Pattern pattern2=Pattern.compile("#A:(\d+)-(.*?)(?=#A:|$)");
Matcher matcher2=pattern2.matcher(line);
while(matcher2.find())
{
int answerID1=Integer.parseInt(matcher2.group(1).trim());
String answer=matcher2.group(2).trim();
answerIDList.add(answerID1);
answerList.add(answer);
}
}
answers.add(new Answer(answerID,studentID,answerIDList,answerList));
}
if(line.startsWith("#X:"))
{
int i=1;
String[] parts=line.split("-");
for(String part:parts)
{
if(i
part=part.replaceAll("#X:","");
String[] studentInformation=part.split("\s+");
students.add(new Student(studentInformation[0],studentInformation[1]));
i++;
}
}
if(line.startsWith("#D:"))
{
int deleteTopicID=Integer.parseInt(line.replaceAll("#D:N-",""));
deleteTopicIDs.add(deleteTopicID);
}
}
else
System.out.println("wrong format:"+line);
}
}
for(int deleteTopicID:deleteTopicIDs)
for(Topic topic:topics)
if(deleteTopicID==topic.getTopicID())
topic.deleteTopic();
for(Exam exam:exams)
{
exam.chooseTopics(topics);
exam.judgePoint();
}
for(Answer answer:answers)
{
if(!answer.setExam(exams))
continue;
answer.setStudent(students);
answer.correctExam();
}
}
}
(2)踩坑心得:
根据题目要求写出对应代码后出现了上述问题,经过自己思考和与别人讨论得出是因为在加入学生信息和加入试卷信息时没有判断该信息是否在一直的列表中存在,后面经过修改在Answer类中定义的判断方法中加入布尔值判断所给的学生和题目是否在所给列表中,对不同的布尔值进行不同的处理。
(3)改进建议:
answer类中的correctTopic方法嵌套层数过多,可以将判断学生信息的方法放入学生类中,将判断试卷是否存在的方法放入试卷类中,返回一个布尔值,在答案类中调用方法判断,减少代码的嵌套率,增强复用性
三.总结
通过本次的三次大作业,我学习了面向对象编程的基本原理,包括类、对象、封装、正则表达式等概念,以及如何在编程中应用这些原理。学习了一门具体的编程语言,掌握了其语法和特性,并了解了如何使用该语言进行面向对象编程。通过完成作业和实验,提升了自己的编程实践能力,掌握了解决实际问题的方法和技巧。在今后的学习中可以将相似的功能封装成方法或者类,可以提高代码的复用性和可维护性。以后在实现代码的过程中可以适当加入一些注释,代码应该易于理解,包括给变量和方法起一个有意义的名字,添加注释来解释代码的作用和逻辑。这样可以让其他人更容易理解代码,也方便自己日后的维护和修改。
改进意见:课程安排应该注重实践,通过编写代码和完成项目来巩固所学知识,这样可以帮助学生更好地理解和掌握面向对象编程的技术。作业和实验应该设计成能够引导学生独立思考和解决问题的形式,而不是简单地要求完成任务。这样可以培养学生的创造力和解决问题的能力。教师应该及时提供学生的作业和实验的反馈,指导学生发现问题并改进。这样可以帮助学生不断提高自己的编程水平。课程教学方式可以多样化,包括讲解、示范、讨论、案例分析等,以满足不同学生的学习需求和方式。教师可以通过生动的案例和实际应用场景来激发学生对编程的兴趣,让学生能够主动参与学习,提高学习的效果和质量。