答题判题程序
题目要求
设计实现答题程序,模拟一个小型的测试,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果。
详见: 答题判题程序
前言
前两次作业较为的输入较为简单
但第三次作业的难度就提升的挺多, 需要考虑到多种情况。
为了尽可能完美写出这道题目,首先我们要构建出合适的类, 并处理好类和类之间的关系. 这样一来, 在复杂的输入情况下, 不容易把程序写乱.
再此我推荐大家用ArraryList结果来写出这道题。
设计与分析
类的设计
在这道题目中,我们定义了学生类,试卷类,试题类,答卷类来完成这道题目。
其中
学生类:中定义了学号,姓名。
试卷类:存储了试卷编号,题目数组和得分数组,其中题目数组的下标对应得分数组的下标。
答卷类:储存了答卷号,学生id,题序,回答和得分。
试题类:储存了题目,题号,正确答案,题目是否存在(作于之后判断题目是否被删除)。
学生类
学生类包含学生的学号, 姓名, 以及一个用于存储读取到的学生的静态的list对象students
package PTA3;
public class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
题目类
题目类包含题目的题号、题目内容、标准答案以及用静态list对象存储所有读取到的题目
题目类中的isTrue成员,表示题目是否有效,即是否被删除
题目类源码
package PTA3;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Question {
private String questions;
private int num;
private String answer;
private boolean isTrue;
public Question( int num, String questions,String answer) {
this.questions = questions;
this.num = num;
this.answer = answer;
this.isTrue=true;
}
public String getQuestions() {
return questions;
}
public void setQuestions(String questions) {
this.questions = questions;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public boolean isIstrue() {
return isTrue;
}
public void setIstrue(boolean istrue) {
this.isTrue = istrue;
}
}
试卷类
试卷类中包含该试卷号, 试卷中的题目(使用list存储), 题目对应的分值(用list存储), 以及用静态list对象testPapers
存储读取到的所有试卷
package PTA3;
import java.util.ArrayList;
public class TestPaper {
private int count;
private ArrayList<Integer> nums;
private ArrayList<Integer> scores;
public TestPaper(int count, ArrayList<Integer> nums, ArrayList<Integer> scores) {
this.count = count;
this.nums = nums;
this.scores = scores;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public ArrayList<Integer> getNum() {
return nums;
}
public void setNum(ArrayList<Integer> num) {
this.nums = num;
}
public ArrayList<Integer> getScore() {
return scores;
}
public void setScore(ArrayList<Integer> score) {
this.scores = score;
}
public void showTest()
{
System.out.println(getCount());
for(int n:nums)
{
System.out.println(n);
}
for(int n:scores)
{
System.out.println(n);
}
}
}
答卷类
package PTA3;
import java.util.ArrayList;
public class Answer {
private int num;
private String id;
private ArrayList<Integer> number;
private ArrayList<String> answers;
private ArrayList<Integer>scores;
public ArrayList<Integer> getScores() {
return scores;
}
public void setScores(ArrayList<Integer> scores) {
this.scores = scores;
}
public Answer() {
}
public Answer(int num, String id, ArrayList<Integer> number, ArrayList<String> answers) {
this.num = num;
this.id = id;
this.number = number;
this.answers = answers;
this.scores=new ArrayList<>();
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ArrayList<Integer> getNumber() {
return number;
}
public void setNumber(ArrayList<Integer> number) {
this.number = number;
}
public ArrayList<String> getAnswers() {
return answers;
}
public void setAnswers(ArrayList<String> answers) {
this.answers = answers;
}
}
输入
通过循环判断最后一次输入是否为end如果为end则结束输入
具体过程
-
循环方法
while(!(input=scanner.nextLine()).equals("end"))
- 判断每次输入的input的形式,选择对应进入那一条if语句
-
针对不同种信息的输入
-
输入题目
inputQuestion
方法用于输入题目
if (input.startsWith("#N:")) { Matcher question = p.matcher(input); Matcher wrongQuestion= wp.matcher(input); if (question.find()) { Question qs = new Question(Integer.parseInt(question.group(1)), question.group(2), question.group(3)); questionlist.add(qs); } else { System.out.println(); System.out.println("wrong format:"+input); } } 其中判断开头输入为#N:,就进入录入题库。通过正则表达式把录入的信息存储在题目类的对象当中,并再存入进List当中。
-
-
-
输入试卷
else if(input.startsWith("#T:")){ String testPattern = "^#T:(\\d+)(?: (\\d+-\\d+))*"; Pattern testP=Pattern.compile(testPattern); Matcher test=testP.matcher(input); if(test.matches()){ Pattern pp = Pattern.compile("(\\d+)-(\\d+)"); Matcher m = pp.matcher(input); int count=Integer.parseInt(test.group(1)); while(m.find()){ int num = Integer.parseInt(m.group(1)); int score = Integer.parseInt(m.group(2)); questionnum.add(num); scorelist.add(score); } TestPaper newtest=new TestPaper(count,questionnum,scorelist); testList.add(newtest); }else { System.out.println("wrong format:"+input); } }
-
输入答卷
else if (input.startsWith("#S:")) { String pattern = "^#S:(\\d+) (\\d{8}) #A:(\\d+-\\d+)(?: #A:(\\d+-\\d+))*"; Pattern answer=Pattern.compile(pattern); Matcher m=answer.matcher(input); if(m.matches()){ int count=Integer.parseInt(m.group(1)); String ID=m.group(2); String pp="(\\d+)-(\\d+)"; Pattern c=Pattern.compile(pp); Matcher v=c.matcher(input); ArrayList<Integer> nums=new ArrayList<>(); ArrayList<String> answers=new ArrayList<>(); while(v.find()){ nums.add(Integer.parseInt(v.group(1))); answers.add((v.group(2))); } newAnswer=new Answer(Integer.parseInt(m.group(1)),(m.group(2)),nums,answers); answerArrayList.add(newAnswer); }else{ System.out.println("wrong format:"+input); } }
-
输入学生
input Student
方法用于输入学生else if (input.startsWith("#X:")) { String pattern = "(\\d{8})\\s(\\w+)"; String pattern1 ="^#X:(\\d{8})\\s+(\\w+)(?:\\-\\d{8}\\s+(\\w+))*"; Pattern p1 = Pattern.compile(pattern); Pattern p2 = Pattern.compile(pattern1); Matcher m = p1.matcher(input); Matcher m2 = p2.matcher(input); if(m2.matches()==false){ System.out.println("wrong format:"+input); }else{ while (m.find()) { String id = m.group(1); String name = m.group(2); Student newStudent=new Student(id,name); studentArrayList.add(newStudent); } } }
-
输入删除题目信息
else if(input.startsWith("#D:")){ String pattern="^#D:N-(\\d+)"; Pattern delp=Pattern.compile(pattern); Matcher m=delp.matcher(input); if(m.find()) { delList.add(Integer.parseInt(m.group(1))); for(int i:delList) { for(int j=0;j<questionlist.size();j++) { if(questionlist.get(j).getNum()==i){ questionlist.get(j).setIstrue(false); } } } }else{ System.out.println("wrong format:"+input); } }
-
输出
本题的输出主要分为两种: 错误信息输出和答卷信息输出
错误信息输出
错误信息输出主要是总分不为100时的提示, 格式错误提示, 题目不存在, 题目无效, 试卷不存在, 学生不存在.
其中总分不为100及格式错误提示, 在输入时已经以异常处理的方式进行输出了
而其他的错误信息输出, 则应当在答卷信息输出的同时进行输出
答卷信息输出
我们在List
中存储了多张答卷的信息, 现在我们只需要对这多张答卷分别进行输出
而对答卷输出, 则分为以下步骤:
- 检查试卷是否存在, 如果不存在, 输出试卷不存在错误提示, 输出结束
- 遍历试卷中的每一道题目, 若题目不存在或无效则输出相应错误提示, 题目存在则输出题目
- 检查学生是否存在, 若存在则输出学生信息和得分情况. 不存在则输出学生不存在错误提示
int sum=0;
int idex=newAnswer.getNum();
for(TestPaper pi:testList){
if(pi.getCount()==idex){
for(int n:pi.getScore()){
sum+=n;
}
}
}
if(sum!=100){
System.out.println("alert: full score of test paper1 is not 100 points");
}
//开始了哈
String questionp=null;
String rightAnswer=null;
String answer=null;
boolean isTestExsist=false;
boolean isStudent=false;
int score=0;
int idexp= newAnswer.getNum();
for(TestPaper pp:testList){
//找到对应的答卷
if(pp.getCount()==idexp){
//通过试卷题号到题库找题目
System.out.println("find text");
isTestExsist=true;
for(int i=0;i<pp.getNum().size();i++){
boolean isWritetest=false;
boolean isFindtest=false;
boolean istestexsite=false;
boolean isRight=false;
boolean isAnwer=false;
for(int j=0;j<questionlist.size();j++){
//比对第一题
if(pp.getNum().get(i)==questionlist.get(j).getNum()){
questionp=questionlist.get(j).getQuestions();
rightAnswer=questionlist.get(j).getAnswer();
isFindtest=true;
if(questionlist.get(j).isIstrue()==true){
istestexsite=true;
}
break;
}
}//到题目找完了题目,现在开始比对
for(int x=0;x<newAnswer.getNumber().size();x++){
if(i+1==newAnswer.getNumber().get(x)){
answer=newAnswer.getAnswers().get(x);
isWritetest=true;
break;
}
}
if(answer.equals(rightAnswer)&&istestexsite){
isRight=true;
score+=pp.getScore().get(i);
newAnswer.getScores().add(pp.getScore().get(i));
}
else {
newAnswer.getScores().add(0);
}
if(istestexsite&&isFindtest&&isWritetest){
System.out.println(questionp+"~"+answer+"~"+isRight);
} else if (isFindtest==false) {
System.out.println("non-existent question~0");
} else if (isWritetest==false) {
System.out.println("answer is null");
} else if (istestexsite==false) {
int k=i+1;
System.out.println("the question "+k+" invalid~0");
}
}
String id=newAnswer.getId();
String name=null;
for(Student student:studentArrayList){
if(student.getId().equals(newAnswer.getId())){
name=student.getName();
isStudent=true;
System.out.print(id+" "+name+":");
for(int n:newAnswer.getScores()){
System.out.print(" "+n);
}
System.out.print("~"+score);
}
}
if(isStudent==false){
System.out.println(id+" not found");
}
}else{
System.out.println("not find");
}
}
if(isTestExsist==false){
System.out.println("The test paper number does not exist");
}
完整源码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
ArrayList<Question> questionlist = new ArrayList<>();
ArrayList<TestPaper> testList=new ArrayList<>();
String input;
ArrayList<Integer>questionnum=new ArrayList<>();
ArrayList<Integer>scorelist=new ArrayList<>();
ArrayList<Student>studentArrayList=new ArrayList<>();
ArrayList<Answer>answerArrayList=new ArrayList<>();
ArrayList<Integer>delList=new ArrayList<>();
Answer newAnswer=new Answer();
//循环输入各类信息
while(!(input=scanner.nextLine()).equals("end")) {
//比对信息然后进入不同的循环
//输入的题目类型
if (input.startsWith("#N:")) {
String patter="#N:(\\d+) #Q:(.+) #A:(\\d+)";
Pattern p=Pattern.compile(patter);
Matcher question = p.matcher(input);
if (question.find()) {
Question qs = new Question(Integer.parseInt(question.group(1)), question.group(2), question.group(3));
questionlist.add(qs);
} else {
System.out.println("wrong format:"+input);
}
}
//输入试卷类型
else if(input.startsWith("#T:")){
String testPattern = "^#T:(\\d+)(?: (\\d+-\\d+))*";
Pattern testP=Pattern.compile(testPattern);
Matcher test=testP.matcher(input);
if(test.matches()){
Pattern pp = Pattern.compile("(\\d+)-(\\d+)");
Matcher m = pp.matcher(input);
int count=Integer.parseInt(test.group(1));
while(m.find()){
int num = Integer.parseInt(m.group(1));
int score = Integer.parseInt(m.group(2));
questionnum.add(num);
scorelist.add(score);
}
TestPaper newtest=new TestPaper(count,questionnum,scorelist);
testList.add(newtest);
}else {
System.out.println("wrong format:"+input);
}
} else if (input.startsWith("#X:")) {
String pattern = "(\\d{8})\\s(\\w+)";
String pattern1 ="^#X:(\\d{8})\\s+(\\w+)(?:\\-\\d{8}\\s+(\\w+))*";
Pattern p1 = Pattern.compile(pattern);
Pattern p2 = Pattern.compile(pattern1);
Matcher m = p1.matcher(input);
Matcher m2 = p2.matcher(input);
if(m2.matches()==false){
System.out.println("wrong format:"+input);
}else{
while (m.find()) {
String id = m.group(1);
String name = m.group(2);
Student newStudent=new Student(id,name);
studentArrayList.add(newStudent);
}
}
} else if (input.startsWith("#S:")) {
String pattern = "^#S:(\\d+) (\\d{8}) #A:(\\d+-\\d+)(?: #A:(\\d+-\\d+))*";
Pattern answer=Pattern.compile(pattern);
Matcher m=answer.matcher(input);
if(m.matches()){
int count=Integer.parseInt(m.group(1));
String ID=m.group(2);
String pp="(\\d+)-(\\d+)";
Pattern c=Pattern.compile(pp);
Matcher v=c.matcher(input);
ArrayList<Integer> nums=new ArrayList<>();
ArrayList<String> answers=new ArrayList<>();
while(v.find()){
nums.add(Integer.parseInt(v.group(1)));
answers.add((v.group(2)));
}
newAnswer=new Answer(Integer.parseInt(m.group(1)),(m.group(2)),nums,answers);
answerArrayList.add(newAnswer);
}else{
System.out.println("wrong format:"+input);
}
}else if(input.startsWith("#D:")){
String pattern="^#D:N-(\\d+)";
Pattern delp=Pattern.compile(pattern);
Matcher m=delp.matcher(input);
if(m.find())
{
delList.add(Integer.parseInt(m.group(1)));
for(int i:delList) {
for(int j=0;j<questionlist.size();j++)
{
if(questionlist.get(j).getNum()==i){
questionlist.get(j).setIstrue(false);
}
}
}
}else{
System.out.println("wrong format:"+input);
}
}
// questionlist.showlist();
// testList.showTestList();
}
int sum=0;
int idex=newAnswer.getNum();
for(TestPaper pi:testList){
if(pi.getCount()==idex){
for(int n:pi.getScore()){
sum+=n;
}
}
}
if(sum!=100){
System.out.println("alert: full score of test paper1 is not 100 points");
}
//开始了哈
String questionp=null;
String rightAnswer=null;
String answer=null;
boolean isTestExsist=false;
boolean isStudent=false;
int score=0;
int idexp= newAnswer.getNum();
for(TestPaper pp:testList){
//找到对应的答卷
if(pp.getCount()==idexp){
//通过试卷题号到题库找题目
System.out.println("find text");
isTestExsist=true;
for(int i=0;i<pp.getNum().size();i++){
boolean isWritetest=false;
boolean isFindtest=false;
boolean istestexsite=false;
boolean isRight=false;
boolean isAnwer=false;
for(int j=0;j<questionlist.size();j++){
//比对第一题
if(pp.getNum().get(i)==questionlist.get(j).getNum()){
questionp=questionlist.get(j).getQuestions();
rightAnswer=questionlist.get(j).getAnswer();
isFindtest=true;
if(questionlist.get(j).isIstrue()==true){
istestexsite=true;
}
break;
}
}//到题目找完了题目,现在开始比对
for(int x=0;x<newAnswer.getNumber().size();x++){
if(i+1==newAnswer.getNumber().get(x)){
answer=newAnswer.getAnswers().get(x);
isWritetest=true;
break;
}
}
if(answer.equals(rightAnswer)&&istestexsite){
isRight=true;
score+=pp.getScore().get(i);
newAnswer.getScores().add(pp.getScore().get(i));
}
else {
newAnswer.getScores().add(0);
}
if(istestexsite&&isFindtest&&isWritetest){
System.out.println(questionp+"~"+answer+"~"+isRight);
} else if (isFindtest==false) {
System.out.println("non-existent question~0");
} else if (isWritetest==false) {
System.out.println("answer is null");
} else if (istestexsite==false) {
int k=i+1;
System.out.println("the question "+k+" invalid~0");
}
}
String id=newAnswer.getId();
String name=null;
for(Student student:studentArrayList){
if(student.getId().equals(newAnswer.getId())){
name=student.getName();
isStudent=true;
System.out.print(id+" "+name+":");
for(int n:newAnswer.getScores()){
System.out.print(" "+n);
}
System.out.print("~"+score);
}
}
if(isStudent==false){
System.out.println(id+" not found");
}
}else{
System.out.println("not find");
}
}
if(isTestExsist==false){
System.out.println("The test paper number does not exist");
}
}
}
class Answer {
private int num;
private String id;
private ArrayList<Integer> number;
private ArrayList<String> answers;
private ArrayList<Integer>scores;
public ArrayList<Integer> getScores() {
return scores;
}
public void setScores(ArrayList<Integer> scores) {
this.scores = scores;
}
public Answer() {
}
public Answer(int num, String id, ArrayList<Integer> number, ArrayList<String> answers) {
this.num = num;
this.id = id;
this.number = number;
this.answers = answers;
this.scores=new ArrayList<>();
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ArrayList<Integer> getNumber() {
return number;
}
public void setNumber(ArrayList<Integer> number) {
this.number = number;
}
public ArrayList<String> getAnswers() {
return answers;
}
public void setAnswers(ArrayList<String> answers) {
this.answers = answers;
}
}
class Question {
private String questions;
private int num;
private String answer;
private boolean isTrue;
public Question( int num, String questions,String answer) {
this.questions = questions;
this.num = num;
this.answer = answer;
this.isTrue=true;
}
public String getQuestions() {
return questions;
}
public void setQuestions(String questions) {
this.questions = questions;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public boolean isIstrue() {
return isTrue;
}
public void setIstrue(boolean istrue) {
this.isTrue = istrue;
}
}
class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class TestPaper {
private int count;
private ArrayList<Integer> nums;
private ArrayList<Integer> scores;
public TestPaper(int count, ArrayList<Integer> nums, ArrayList<Integer> scores) {
this.count = count;
this.nums = nums;
this.scores = scores;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public ArrayList<Integer> getNum() {
return nums;
}
public void setNum(ArrayList<Integer> num) {
this.nums = num;
}
public ArrayList<Integer> getScore() {
return scores;
}
public void setScore(ArrayList<Integer> score) {
this.scores = score;
}
public void showTest()
{
System.out.println(getCount());
for(int n:nums)
{
System.out.println(n);
}
for(int n:scores)
{
System.out.println(n);
}
}
}
踩坑心得
1.正则表达式使用方面
没有处理好像试卷类和学生类信息中,不确定数量的多个信息的录入。
容易导致只匹配到第一条信息而忽略了之后的若干条信息。
还有检查题目信息是否格式正确的时候,使用了m.find()而不是m.martchs这就会导致第一个信息识别出来就会通过,而忽略了之后若干条信息的正确情况。
没有处理好空字符输入
要判断输入为空的情况
改进建议
针对我当前的程序, 还有很多可以改进的地方. 主要时类和类之间的关系处理的不够
总结
在写这三次题目的过程中, 我学会了熟练使用正则表达式,更加深入了解了设计类, 及类与类之间的关系. 熟悉了ArrayList
的基本使用方法