题目集1-3总结
前言
知识点
每次题目集在小题上都能给出新的知识去让我们学习,包括类的构造,类的引用,数组的基本运用,对象的构造,更包括对属性状态的应用,尽管以我们现在的水平还无法真正理解到属性的状态对程序乃至工程整体的作用。另外对于初次接触这样较大型的Java程序时我还是很不适应,好在菜老师的新手指导给予了很大的帮助:不过迭代的难度依旧不小😄
UML图的设计: 确定需求-识别类-定义类的属性集方法-建立类之间的关系-绘制类图-完善类图-验证和改进。
也包括对某些常用类的了解和List集合类型: 例如其中的ListLink集合类型,其中的sort方法——第一次了解重构,time类的应用,通过小练习题中对这些小语法的熟练对我
在迭代题目程序的编写具有很大帮助。
面向对象的设计原则: 这是每个初学Java的人都听说其是编写程序时最为重要,但真正上手时又弃之如敝履的东西。它主要包括七大设计原则:
- 单一职责原则(Single Responsibility Principle,SRP)
- 开放-封闭原则(Open-Closed Principle,OCP)
- 里氏替换原则(Liskov Substitution Principle,LSP)
- 接口隔离原则(Interface Segregation Principle,ISP)
- 依赖倒置原则(Dependency Inversion Principle,DIP)
- 最少知识原则(Least Knowledge Principle,LKP,又称迪米特法则,Law of Demeter,LoD)
- 合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
这里隆重给出
以示作为初学者歉意.....
.
.
.
设计与分析
1.对于第一次题目集最后一道题的分析
初见大boss,才刚开始便觉得无法掌控,主要问题是题目的长度相比于之前的题目更长,之前的程序更多的是对算法和类方法的使用,而这次确是着重于设计之上
一开始,类的设计在蔡柯老师的帮助下逐步完成,完成实体类的编写与照抄无异,这一步骤较为顺利。
之后,对输入数据的匹配,在运用正则表达式时,着实吃了不少苦头,好在此时对输入的数据没有太多变化要求,然而这却是这道题未达到满分的原因。
第一次题目集最后一题

点击查看代码
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question{
private int title = 0;
private String q_information = "";
private String stander_answer = "";
public Question(){
}
public boolean judge1(String answer){ //判断 标答 是否等于 小明答
if(Objects.equals(this.stander_answer, answer)){
return true;
}
else{
return false;
}
}
public String getStander_answer() {
return stander_answer;
}
public void setStander_answer(String stander_answer) {
this.stander_answer = stander_answer;
}
public String getQ_information() {
return q_information;
}
public void setQ_information(String q_information) {
this.q_information = q_information;
}
public int getTitle() {
return title;
}
public void setTitle(int title) {
this.title = title;
}
}
class Paper{
private int number = 0;
private Question[] questions ;
public Paper(int Q_count){
this.number = Q_count;
this.questions = new Question[Q_count+1];
for(int i = 0;i<=Q_count;i++){
questions[i] = new Question();
}
}//初始化 题目列表
public boolean judge2(String answer ,int title){
return Objects.equals(answer, questions[title].getStander_answer());
}
public String seek(int title){
for(int i=0;i<this.number;i++){
if(title == questions[i].getTitle()){
return questions[i].getStander_answer();
}
}
return "";
}
public void setQuestions(int title , String sentence,String answer) {
// 搜索存储对应title的题目
this.questions[title].setStander_answer(answer);
this.questions[title].setTitle(title);
this.questions[title].setQ_information(sentence);
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Question[] getQuestions() {
return questions;
}
// 这里 为试卷对象输入 所有 题目实例
// 如 列表中 questions[2] : title=2;
}
class Script{
private Paper paper ;
private String[] answer_list ;
//答案列表是依照题号顺序的
private boolean[] judge_list ;
public Script(int Q_count){
paper = new Paper(Q_count); // 完成对试卷的初始化
answer_list = new String[Q_count+1];
for (int i = 0; i <=Q_count; i++) {
answer_list[i] = "";
} //完成对答案列表的初始化
judge_list = new boolean[Q_count+1];
Arrays.fill(judge_list, false); //完成对批改列表的初始化
}
public boolean judge3(int title){//第title题是否为第title答案
if(Objects.equals(this.answer_list[title],paper.getQuestions()[title].getStander_answer())){
return true;
}
return false;
}
public void to_printf(int title){
System.out.println(paper.getQuestions()[title].getQ_information() + "~" + answer_list[title]);
}
public void set1_answer(int title,String answer){
this.answer_list[title] = answer;
}//此函数用于初始化答卷类 里的答案列表 需用循环完成
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public String[] getAnswer_list() {
return answer_list;
}
public void setAnswer_list(String[] answer_list) {
this.answer_list = answer_list;
}
public boolean[] getJudge_list() {
return judge_list;
}
public void setJudge_list(boolean[] judge_list) {
this.judge_list = judge_list;
}
}
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int questions_count = scan.nextInt();
scan.nextLine(); // 消耗掉换行符
Script script = new Script(questions_count);
int is_title = 1;
String Qsentence = "";
String stander_answer = "";
String line_paper = "";
String line_script = "";
String my_answer = "";
while(true){
//输入题号
for(int i = 1;i<=questions_count;i++){
line_paper = scan.nextLine();
is_title = getlinecount(line_paper ); // 题号
Qsentence = getQsentence(line_paper);// 问题
stander_answer = getanswer(line_paper);// 标准答案
script.getPaper().setQuestions(is_title,Qsentence,stander_answer);
/* Script.getPaper().getQuestions()[is_title].setTitle(is_title);
Script.getPaper().getQuestions()[is_title].setQ_information(Qsentence);
Script.getPaper().getQuestions()[is_title].setStander_answer(stander_answer);//此时 questions[2] : 题号 2*/
}//初始化题目列表
for(int i = 1;i<=questions_count;i++){ line_script = scan.next();
my_answer = getanswer(line_script);// 我的答案
script.set1_answer(i,my_answer);
// line_script = line_script.replaceFirst("#A","");
}// 初始化答案列表篇
String ending = scan.nextLine();
if(Objects.equals("end",ending)){
break;
}
break;
}
for(int i = 1;i<=questions_count;i++){
System.out.printf("%s~%s\n",script.getPaper().getQuestions()[i].getQ_information(),script.getAnswer_list()[i]);
}
for(int i = 1;i<=questions_count;i++){
System.out.print(script.judge3(i));
if(i!=questions_count){
System.out.print(" ");
}
}
}
static public int getlinecount(String line ){
Pattern r = Pattern.compile("#N:\\s*(\\d+)");
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
int number = Integer.parseInt(m.group(1));
return number;
}
else{
return 0;
}
}
static public String getQsentence(String line ){
Pattern r = Pattern.compile("#Q:\\s*(.+?) #A:");
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
return m.group(1).replace("\\s+","");
}
else{
return "false";
}
}
static public String getanswer(String line ){
Pattern r = Pattern.compile("#A:(\\w+)");
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
return m.group(1);
}
else{
return "false";
}
}
}
这里并没有设计专门的控制类去实现调用各个实体类,进行题目要求的输出以及运算匹配,以下是对主方法中语句作用的解释:
1.Scanner scan = new Scanner(System.in);:创建一个Scanner对象,用于从控制台读取用户的输入。
- int questions_count = scan.nextInt();:从用户输入中读取题目数量。
3.scan.nextLine();:消耗掉换行符,以便后续的输入。
-
Script script = new Script(questions_count);:创建一个Script对象,该对象用于管理题目和答案信息。
-
接下来是一个while循环,该循环用于读取用户输入的题目信息和答案信息,并将其添加到Script对象中。
-
内层的第一个for循环用于读取题目信息,包括题号、问题和标准答案,并将其添加到Script对象中。
-
内层的第二个for循环用于读取答案信息,并将其添加到Script对象中。
-
如果用户输入了"end",则跳出循环。
-
接下来的两个for循环分别用于输出题目和答案信息,并调用judge3方法来判断答案的正确性。
-
getlinecount、getQsentence和getanswer方法分别用于从输入的字符串中提取题号、问题和答案信息,并返回相应的值。
最为主要的设计是,script类依赖Paper,Paper依赖Question,即
script->Paper,,Paper->Question;这就使得每次对实体类的调用都要通过调用答卷类从而使得答卷类的方法,属性是复杂而冗长的。
像一窝大杂烩,回头来看只觉得这代码真丑。。。当然这三次代码都丑
2.对于第二次题目集最后一道题的分析
第一次题目集的迭代一体现我初见较大Java程序的,而对代码的准确度把握有不足,而这一次却是体现对整个程序的的设计,架构的不足。未满足开闭,单一职责,厘米特等法则的情况下,导致了整个程序没有足够的健壮性以及包容,稳定性。由于之前未考虑类之间的耦合性的高低,这迭代二的编写只能从头来过,这无疑是漫长而痛苦的。这里给出UML来对类的设计进行具体的分析:


点击查看代码
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Question implements Comparable<Question>{
private int title = 0;
private String q_information = "";
private String stander_answer = "";
private int scores = 0;
public Question(){
}
@Override
public int compareTo(Question other) {
//按价格进行比较
return Integer.compare(this.title, other.title);
}
public boolean judge1(String answer){ //判断 标答 是否等于 小明答
if(Objects.equals(this.stander_answer, answer)){
return true;
}
else{
return false;
}
}
public String getStander_answer() {
return stander_answer;
}
public void setStander_answer(String stander_answer) {
this.stander_answer = stander_answer;
}
public String getQ_information() {
return q_information;
}
public void setQ_information(String q_information) {
this.q_information = q_information;
}
public int getTitle() {
return title;
}
public void setTitle(int title) {
this.title = title;
}
public int getScores() {
return scores;
}
public void setScores(int scores) {
this.scores = scores;
}
}//00000000000000000000000000000000000000000000000000000000000000000000000
class Paper{
private int title = 1;
private int paper_length = 0;
private LinkedList<Question> question_list = new LinkedList<>();
public Paper(int P_title){
this.title = P_title;
Question question = new Question();
this.question_list.add(question);//占用第0个位置
}
//初始化 题目列表
public boolean judge2(String answer ,int title){
return Objects.equals(answer, question_list.get(title).getStander_answer());
}
public void setAquestion(int title , String sentence, String answer,int sorce) {
Question question = new Question();
question.setStander_answer(answer);
question.setTitle(title);
question.setQ_information(sentence);
question.setScores(sorce);
this.question_list.add(question);
// 搜索存储对应title的题目
}
public Question seek(int title){
for(int i=0;i<this.question_list.size();i++){
if(title == this.question_list.get(i).getTitle()){
return this.question_list.get(i);
}
}
return null;
}
public int getTitle() {
return title;
}
public void setTitle(int title) {
this.title = title;
}
// 这里 为试卷对象输入 所有 题目实例
// 如 列表中 questions[2] : title=2;
public LinkedList<Question> getQuestion_list() {
return question_list;
}
public void setQuestion_list(LinkedList<Question> question_list) {
this.question_list = question_list;
}
public int getPaper_length() {
return paper_length;
}
public void setPaper_length(int paper_length) {
this.paper_length = paper_length;
}
}//11111111111111111111111111111111111111111111111111111111111111111111111111111
class ques_answer implements Comparable<ques_answer>{
private int title = 1;
private String answer = "";
private int score = 0;
public ques_answer(String answer, int score) {
this.answer =answer;
this.score =score;
}
public ques_answer() {
}
@Override
public int compareTo(ques_answer other ){
//按价格进行比较
return Integer.compare(this.title, other.title);
}
public String getAnswer() {return answer;}
public void setAnswer(String answer) {this.answer = answer;}
public int getScore() {return score;}
public void setScore(int score) {this.score = score;}
public int getTitle() {return title;
}
public void setTitle(int title) {this.title = title;}
}//222222222222222222222222222222222222222222222222222222222222222222222222222
class Script implements Comparable<Script>{ //答卷类
@Override
public int compareTo(Script other){
return Integer.compare(this.title,other.title);
}
private int title = 1 ;
private Paper paper ;
private LinkedList<ques_answer> answer_list = new LinkedList<>();
//答案列表是依照题号顺序的
private boolean [] judge_list = new boolean [100];
public Script(int title){
paper = new Paper(title); // 完成对试卷的初始化
Arrays.fill(judge_list, false); //完成对批改列表的初始化
ques_answer answer = new ques_answer();
this.answer_list.add(answer); //占用第0个位置
}
public boolean judge3(int title){//第title题是否为第title答案
if(Objects.equals(this.answer_list.get(title).getAnswer(),paper.getQuestion_list().get(title).getStander_answer())){
return true;
}
return false;
}
public void to_printf(int title){
System.out.println(paper.getQuestion_list().get(title).getQ_information() + "~" + this.answer_list.get(title).getAnswer()+"~"+judge3(title));
}
public void set1_answer(int title,String answer){
ques_answer answer1 = new ques_answer(answer,title);
answer_list.add(answer1);
}//此函数用于初始化答卷类 里的答案列表 需用循环完成
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public boolean[] getJudge_list() {
return judge_list;
}
public void setJudge_list(boolean[] judge_list) {
this.judge_list = judge_list;
}
public int getTitle() {
return title;
}
public void setTitle(int title) {
this.title = title;
}
public LinkedList<ques_answer> getAnswer_list() {return answer_list;}
public void setAnswer_list(LinkedList<ques_answer> answer_list) {this.answer_list = answer_list;}
}
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String stander_answer = "";//问题类题目信息 #N:1 #Q:1+1= #A:2
ArrayList<Script> scripts = new ArrayList<>();//有多少答卷有多少试卷
String line_get = "";//输入的每一行,作为原始行数据
Script script0 = new Script(1); //答卷信息存储中介
scripts.add(script0);//占用第0个位置
// LinkedList
while( true){
line_get = scan.nextLine();
if(Objects.equals("end",line_get)){
break;
}//结束条件
String type = type(line_get);
switch (type){
case "#N:":input_queslist(script0,line_get);break;
case "#T:":input_text(script0,line_get);break;
case "#S:":input_script(script0,line_get,scripts);break;
}
}//初始化题目列表 //题目信息
for (int i=1;i<scripts.size();i++) { //当存在一个有效元素时它的长度为2
warning(scripts.get(i));
}//判断是否满分 1试卷总分警示
if(script0.getTitle()!=script0.getPaper().getTitle()){
System.out.println("The test paper number does not exist");
return;
}
for (int k=1;k<scripts.size();k++) {
Script a = scripts.get(k);
for(int i =1;i<a.getPaper().getPaper_length();i++) {
if(!Objects.equals(a.getAnswer_list().get(i).getAnswer(), "")) {
System.out.println(a.getPaper().getQuestion_list().get(i).getQ_information() + "~" + a.getAnswer_list().get(i).getAnswer()+"~"+a.judge3(i));
}
else {
System.out.println("answer is null");
}
} // 2答卷信息
int all = 0;
for(int i =1;i<a.getPaper().getPaper_length();i++){
if(i<a.getAnswer_list().size()-1) {
System.out.print(a.getAnswer_list().get(i).getScore()+" ");
}
else {
System.out.print(a.getAnswer_list().get(i).getScore()+"~");
}
all = all + a.getAnswer_list().get(i).getScore();
}
System.out.println(all);
}
}
//存储问题链表
static public void input_queslist(Script script,String line){
Question question1 = new Question();
Pattern pattern = Pattern.compile("#N:(\\d+) #Q:(.+?) #A:(\\w+)");
Matcher m = pattern.matcher(line);
while(m.find()){
int t = Integer.parseInt(m.group(1));
question1.setTitle(t);
question1.setQ_information(m.group(2));
question1.setStander_answer(m.group(3));
}
script.getPaper().getQuestion_list().add(question1);
}
static public void input_text(Script script,String line){//#T:1 3-5 4-8 5-
String [] a = line.split(" ");
script.getPaper().setPaper_length(a.length);
// Collections.sort(script.getPaper().getQuestion_list());
Pattern pattern = Pattern.compile("(\\d+)");
Pattern pattern1 = Pattern.compile("(\\d+)-(\\d+)");
Matcher m = pattern.matcher(a[0]);
while(m.find()) {
script.getPaper().setTitle(Integer.parseInt(m.group(1)));//设置编号为1的试卷
}
for(int i = 1;i< a.length;i++){ Matcher m1 = pattern1.matcher(a[i]);
while(m1.find()) {
//设置题目title总分为 score
script.getPaper().seek(Integer.parseInt(m1.group(1))).setScores(Integer.parseInt(m1.group(2)));
}
}
}
static public void input_script(Script script,String line,ArrayList<Script> scripts){//#S:1 #A:5 #A:22
while (script.getAnswer_list().size()!=script.getPaper().getPaper_length()){
ques_answer answer_null = new ques_answer();
script.getAnswer_list().add(answer_null);
}
//使答卷列表长度等于问卷列表长度
Script script1 = new Script(1);
String [] a = line.split(" ");
Pattern pattern = Pattern.compile("(\\d+)");
Pattern pattern1 = Pattern.compile("#A:(\\d+)");
Matcher m = pattern.matcher(a[0]);
while(m.find()) {
script.setTitle(Integer.parseInt(m.group(1)));//设置此答卷的标号
}
Matcher m1 = pattern1.matcher(line);
int k = 1;
while(m1.find()){
script.getAnswer_list().get(k).setAnswer(m1.group(1));
if(script.judge3(k)){
script.getAnswer_list().get(k).setScore(script.getPaper().getQuestion_list().get(k).getScores());
}
else{
script.getAnswer_list().get(k).setScore(0);
}
k++;
}
script1=script;
scripts.add(script1);
}
static public void warning(Script script){
int all_grade = 0;
for(Question q:script.getPaper().getQuestion_list()){
all_grade = all_grade + q.getScores();
}
if(all_grade==100){
return;
}
else{
System.out.println("alert: full score of test paper"+script.getPaper().getTitle()+" is not 100 points");
}
}
static public String type(String line){
if(line.contains("#N:")){
return "#N:";
}
if(line.contains("#T:")){
return "#T:";
}
if(line.contains("#S:")){
return "#S:";
}
return "";
}
}
千里之堤,溃于蚁穴
对迭代二的设计,考虑到多套信息的输入,想要对每一个存储信息类,定义一个对应的信息存储中介来临时存储每类信息并把他们加进各个类型数据的容器存储类链表中,然而此处引发了一个巨大的bug,使得解决这个问题只有重新主函数的构造,亦或者使用深拷贝。当然这里没用成。具体放在踩坑心得上讲。
考虑到单项多步调用会造成许多问题,这里将script中的Paper单独拿出来简化了类之间的关联,降低了类之间的耦合性。
对链表排序的设计,应用了Comparable接口,对链表内的元素进行排序。这里用了LinkdList以及ArrayList的容器类类型。
下面是对主方法语句的分析:
解释一下其中的语句:
-
String lineGet = "";: 这行代码声明并初始化了一个字符串变量lineGet,用于存储从命令行读取的输入内容。
-
Script script0 = new Script(1);: 这行代码创建了一个名为script0的Script对象,并传入了一个整数参数1。
-
scripts.add(script0);: 这行代码将刚创建的script0对象添加到了scripts列表中。
-
Scanner scan = new Scanner(System.in);: 这行代码创建了一个Scanner对象scan,用于从标准输入流(命令行)中读取用户的输入。
-
while (true) { ... }: 这是一个无限循环,程序将在此处等待用户的输入,并根据输入内容执行相应的操作,直到用户输入了"end",才会退出循环。
-
lineGet = scan.nextLine();: 这行代码读取用户输入的下一行内容,并将其存储在lineGet变量中。
-
if (Objects.equals("end", lineGet)) { break; }: 这行代码检查用户输入的内容是否等于"end",如果是,则退出循环,结束程序。
-
String type = getType(lineGet);: 这行代码调用了一个名为getType的方法,根据输入的内容判断其类型,并将结果存储在type变量中。
-
switch (type) { ... }: 这是一个switch语句,根据type变量的值执行不同的操作。根据输入的类型,程序将调用不同的方法来处理输入的内容。
-
for (int i = 1; i < scripts.size(); i++) { warning(scripts.get(i)); }: 这是一个for循环,用于对scripts列表中的每个Script对象进行警告处理。
-
if (!Objects.equals(script0.getTitle(), script0.getPaper().getTitle())) { ... }: 这行代码检查script0对象的标题是否与其试卷的标题相匹配,如果不匹配,则输出提示信息并返回。
-
接下来的for循环用于遍历scripts列表中的每个Script对象,并输出每个问题的信息、答案和评分,以及整体得分。
这是本应在控制类而实际在主类里的输入方法:
input_queslist(Script script,String line):此方法用于解析包含问题信息的行,例如问题编号、文本和标准答案。它创建一个 Question 对象,设置其属性,并将其添加到 Script 对象中的问题列表中。
input_text(Script script,String line):该方法用于处理包含试卷结构信息的行。它根据提供的信息设置试卷的长度、标题和每个问题的分数。
input_script(Script script,String line,LinkedList Script scripts):此方法处理与试卷答卷或答题卡相关的输入。它解析行以提取有关答卷标题和答案的信息,根据答案是否正确设置每个答案的分数,并将答卷添加到答卷列表中。
warning(Script script):此方法通过将所有问题的分数相加来计算试卷的总分。如果总分不等于 100,则打印警告消息,指示试卷的满分不是 100 分。
type(String line):此方法根据行中特定的关键词(#N:、#T:、#S:)确定输入行的类型。它返回行的识别类型。
3.对于第三次题目集最后一道题的分析
“谋定而后动,不失其序。”
--这次在编写迭代三程序时终于学聪明了,在着手编写迭代三时,总结前面的教训我首先设计了一张UML图,其中包含我对迭代三题目需求的认识,以及构造相应的类去实现所需要的功能。
-- 而在UML设计之后,又恶补了迭代二没有实现的设计:深度拷贝。使用数据存储中介,以对象为单位去存储,在基本明白深度拷贝的原理并且使用简单的例子去验证之后,才将这类接口引用至迭代三当中。
-- 为应对 题目是否存在 题目是否被删除 题目是否无答案 我设计了题库类去分部实现此功能。并且对问题,答案这样的实体类增加了描述其状态的属性。以便判断情况给出相应的输出。


以下是对应的代码
点击查看代码
以下是对主方法的的分析:
ArrayListScript script_list = new ArrayList<>(); - 创建一个 ArrayList 对象 script_list,用于存储 Script 类型的对象。
ArrayList
ArrayList
Depot depot0 = new Depot(); - 创建一个 Depot 类型的对象 depot0。
Script script0 = new Script(); - 创建一个 Script 类型的对象 script0。
Paper paper0 = new Paper(); - 创建一个 Paper 类型的对象 paper0。
Delete delete = new Delete(); - 创建一个 Delete 类型的对象 delete。
Student student0 = new Student(); - 创建一个 Student 类型的对象 student0。
String line_get = ""; - 创建一个空字符串 line_get,用于存储用户输入的一行文本。
Interface inter_face = new Interface(); - 创建一个 Interface 类型的对象 inter_face。
while (true) { - 进入一个无限循环,直到用户输入了 “end” 才退出循环。
line_get = scan.nextLine(); - 从标准输入流中读取用户输入的一行文本,并将其存储在 line_get 中。
if(!inter_face.check_format(line_get)){continue;} - 调用 inter_face 对象的 check_format 方法检查用户输入的文本格式是否符合要求,如果不符合则跳过本次循环继续等待用户输入。
if (Objects.equals(line_get, "end")) { break; } - 如果用户输入了 “end”,则退出循环,结束程序。
else if (line_get.contains("#N:")) { Controller.input_queslist(depot0, line_get);} - 如果用户输入的文本包含 “#N:”,则调用 Controller 类的 input_queslist 方法,将输入的内容解析并存储到 depot0 对象中。
else if (line_get.contains("#T:")) { Controller.input_text(paper0, line_get, depot0);...} - 如果用户输入的文本包含 “#T:”,则调用 Controller 类的 input_text 方法,将输入的内容解析并存储到 paper0 对象中,然后将 paper0 克隆一份加入 paper_list。
else if (line_get.contains("#S:")) { Controller.input_script(script0, line_get);...} - 如果用户输入的文本包含 “#S:”,则调用 Controller 类的 input_script 方法,将输入的内容解析并存储到 script0 对象中,然后将 script0 克隆一份加入 script_list。
else if (line_get.contains("#X:")) { Controller.input_X(student0, line_get, student_list); } - 如果用户输入的文本包含 “#X:”,则调用 Controller 类的 input_X 方法,将输入的内容解析并存储到 student0 对象中,并将其加入 student_list。
else if (line_get.contains("#D:")) { ...} - 如果用户输入的文本包含 “#D:”,则执行相应的操作,具体操作需要通过正则表达式解析得到命令,然后调用 delete 对象的相应方法进行处理。
for(Script s:script_list){...} - 遍历 script_list 中的每个 Script 对象,依次执行其中的评分操作和输出操作。
对新加的重要实体类,删除类的分析:
depot0.check_depot(this.x).setScores(0);
在题库depot0中查找标题为this.x的问题,并将其分数设置为0,表示此问题无效或已被删除。
depot0.check_depot(this.x).setQ_information("the question "+this.x+" invalid");
同样找到题库中的对应问题,设置问题信息为"the question "+this.x+" invalid",明确表明此问题已失效。
depot0.check_depot(this.x).setCondition(null);
将题库中对应问题的条件(condition)设为null,可能是移除与其相关的任何附加条件或限制。
随后是一个嵌套循环:
外层循环遍历了所有的试卷列表paper_list。
内层循环遍历每个试卷p中的问题列表p.getQuestion_list()。
if(q.getTitle()==this.x){
当发现某个问题的标题与要删除的问题标题this.x相同时,执行以下操作:
q.setCondition(null);
将当前试卷中对应问题的条件设为null。
q.setQ_information("the question "+this.x+" invalid");
设置当前试卷中对应问题的信息为已失效。
q.setStander_answer("");
踩坑心得
|
1.不考虑类的设计原则面向对象的设计原则:
使得类的职责多样,造成编写的困难,更为致命的是写程序时,想到哪写到哪,在没有能力掌控整个代码的情况下,这样做无疑会导致整个程序的崩盘。这是踩到的最大的坑 |
|
2.将类的对象之间进行赋值,造成关联影响
即改变原来对象的属性,被赋值的对象也受到影响,如同c语言指针一样,这个bug一度让我的迭代二瘫痪:以下是对相关问题的资料解答: |

| 3.Java堆空间溢出:
|
|
正则表达式的使用错误:
|
改进建议
对于三次迭代,其实改进的地方是共通的,最为主要的还是这篇blog反复提到的问题,面向对象程序中类的设计:
我应该对迭代一,迭代二,中的试卷类从中分离出一个题库类,当然,试卷类依旧含有问题类集合。对正则输入的方法单独放进一个Contraller类中,以及相关的匹配和上文提到的check方法。再构造一个接口类,应对输出,这样对于题目的迭代也会有较好的可塑性,提升可持续改进的能力。
将实体类集合,比如Linkedlist//<student//>//<question//>//<answer//>使用Map类型的集合,简化数据的调用,清晰代码的结构。
总结
一.学到了什么
二.进一步学习和研究接口的使用,在用过之后发现这真是一个很好的工具帮助程序更为直接的达到要求。方法的重写,以及类的设计。以及简化代码,增加代码清晰度的能力。 三.改进建议希望题目和测试点的文字说明能够更加清晰,有序。希望能延长在实验室学习的时间,每次到8点40就开始赶人实在是很无奈🤷 |




浙公网安备 33010602011771号