OO第一次博客作业
(1)前言
- 这三次题目集的知识点,主要分布在OOP的封装、正则表达式、字符串的合理使用、Java中的集合类的合理选择和使用、对于用户错误输入的控制。
- 对于题量和难度的话,其实算适中,主要是由于我刚刚学习Java语言,思维方式还没有完全从面向过程转到面向对象,在有些方面上还是始终用面向过程的思维去解决我们的pta大作业,程序设计方面,我一直都没有相通怎么样才算面向对象,而且再加上上学期c语言本身就没有怎么过关的我,这也导致我刚开始写pta的时候确实有些吃力。
(2)设计与分析
-题目集1
源代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 这里是读取题目数目
int numQuestions = scanner.nextInt();
// 这里是读取题目
TestPaper testPaper = new TestPaper();
testPaper.readQuestions(scanner, numQuestions);
// 这里是读取和存储
AnswerSheet answerSheet = new AnswerSheet();
answerSheet.readAnswers(scanner);
// 获取题目列表和用户答案列表
List<Question> questions = testPaper.getQuestions();
List<String> userAnswers = answerSheet.getAnswers();
// 按照题号排序题目和用户答案
Collections.sort(questions, Comparator.comparingInt(Question::getNumber));
List<String> sortedUserAnswers = new ArrayList<>(Collections.nCopies(numQuestions, ""));
for (int i = 0; i < numQuestions; i++) {
sortedUserAnswers.set(questions.get(i).getNumber() - 1, userAnswers.get(i));
}
// 输出题目及用户答案
for (Question question : questions) {
String userAnswer = sortedUserAnswers.get(question.getNumber() - 1); // Adjust index
System.out.println(question.getContent() + "~" + userAnswer);
}
// 评判用户答案
for (int i = 0; i < numQuestions; i++) {
Question question = questions.get(i);
String userAnswer = sortedUserAnswers.get(question.getNumber() - 1); // Adjust index
boolean result = userAnswer.equals(question.getCorrectAnswer());
System.out.print(result ? "true" : "false");
if (i != numQuestions - 1) {
System.out.print(" ");
}
}
}
}
class Question {
private int number;
private String content;
private String correctAnswer;
public Question(int number, String content, String correctAnswer) {
this.number = number;
this.content = content;
this.correctAnswer = correctAnswer;
}
public int getNumber() {
return number;
}
public String getContent() {
return content;
}
public String getCorrectAnswer() {
return correctAnswer;
}
}
class TestPaper {
private List
public TestPaper() {
questions = new ArrayList<>();
}
public void addQuestion(Question question) {
questions.add(question);
}
public List<Question> getQuestions() {
return questions;
}
public void readQuestions(Scanner scanner, int numQuestions) {
scanner.nextLine(); // Consume newline
for (int i = 0; i < numQuestions; i++) {
String line = scanner.nextLine();
String[] parts = line.split("#N:| #Q:| #A:");
int number = Integer.parseInt(parts[1].trim());
String content = parts[2].trim();
String correctAnswer = parts[3].trim();
addQuestion(new Question(number, content, correctAnswer));
}
}
}
class AnswerSheet {
private List
public AnswerSheet() {
answers = new ArrayList<>();
}
public void addAnswer(String answer) {
answers.add(answer);
}
public List<String> getAnswers() {
return answers;
}
public void readAnswers(Scanner scanner) {
String line;
while (!(line = scanner.nextLine()).equals("end")) {
String[] answers = line.split("#A:| ");
for (String answer : answers) {
if (!answer.equals("")) {
addAnswer(answer);
}
}
}
}
}
由于这道题比较简单,复杂度上并不是特别大
对于这道题目,现在分析的话,会发现有好多问题
- 依然使用的是面向过程的思路来写题目的,对类的使用不太灵活,面向过程的思想还是没有改变过来
- 主函数存在大量代码,没有设计方法来封装这些代码
- public和private使用混乱,类里面的功能单一,大部分的功能都在主函数中
-题目集2
源代码:
import java.util.*;
class Question {
String questionNumber;
String questionContent;
String correctAnswer;
public Question(String questionNumber, String questionContent, String correctAnswer) {
this.questionNumber = questionNumber;
this.questionContent = questionContent;
this.correctAnswer = correctAnswer;
}
public String getQuestionNumber() {
return questionNumber;
}
public String getQuestionContent() {
return questionContent;
}
public String getCorrectAnswer() {
return correctAnswer;
}
}
class TestPaper {
String paperNumber;
Map<String, Integer> questionScores;
public TestPaper(String paperNumber) {
this.paperNumber = paperNumber;
this.questionScores = new LinkedHashMap<>();
}
public void addQuestionScore(String questionNumber, int score) {
questionScores.put(questionNumber, score);
}
public String getPaperNumber() {
return paperNumber;
}
public Map<String, Integer> getQuestionScores() {
return questionScores;
}
}
class AnswerSheet {
String paperNumber;
List
public AnswerSheet(String paperNumber) {
this.paperNumber = paperNumber;
this.answers = new ArrayList<>();
}
public void addAnswer(String answer) {
answers.add(answer);
}
public String getPaperNumber() {
return paperNumber;
}
public List<String> getAnswers() {
return answers;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<String, Question> questionBank = new LinkedHashMap<>();
Map<String, TestPaper> testPapers = new LinkedHashMap<>();
List
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.equals("end")) {
break;
}
if (line.startsWith("#N:")) {
String[] parts = line.split(" ");
String questionNumber = parts[0].substring(3);
String questionContent = parts[1].substring(3);
String correctAnswer = parts[2].substring(3);
questionBank.put(questionNumber, new Question(questionNumber, questionContent, correctAnswer));
} else if (line.startsWith("#T:")) {
String[] parts = line.split(" ");
String paperNumber = parts[0].substring(3);
TestPaper testPaper = new TestPaper(paperNumber);
for (int i = 1; i < parts.length; i++) {
String[] scorePair = parts[i].split("-");
testPaper.addQuestionScore(scorePair[0], Integer.parseInt(scorePair[1]));
}
testPapers.put(paperNumber, testPaper);
} else if (line.startsWith("#S:")) {
String[] parts = line.split(" ");
String paperNumber = parts[0].substring(3);
AnswerSheet answerSheet = new AnswerSheet(paperNumber);
for (int i = 1; i < parts.length; i++) {
answerSheet.addAnswer(parts[i].substring(3));
}
answerSheets.add(answerSheet);
}
}
int flag = 0;
for (AnswerSheet answerSheet : answerSheets) {
TestPaper testPaper = testPapers.get(answerSheet.getPaperNumber());
List<String> answers = answerSheet.getAnswers();
int totalScore = 0;
boolean scoreAlert = false;
int[] scores = new int[testPaper.getQuestionScores().size()];
int allScore = 0;
for (String questionNumber : testPaper.getQuestionScores().keySet()) {
int score = testPaper.getQuestionScores().get(questionNumber);
allScore += score;
}
for (int i = 0; i < answers.size(); i++) {
String questionNumber = (String) testPaper.getQuestionScores().keySet().toArray()[i];
int score = testPaper.getQuestionScores().get(questionNumber);
Question question = questionBank.get(questionNumber);
String userAnswer = answers.get(i);
boolean isCorrect = userAnswer.equals(question.getCorrectAnswer());
if (isCorrect) {
totalScore += score;
scores[i] = score;
} else
scores[i] = 0;
if (allScore != 100 && !scoreAlert && flag == 0) {
if(testPaper.getQuestionScores().size()>answers.size())
flag=0;
else
flag = 1;
System.out.println("alert: full score of test paper " + testPaper.getPaperNumber() + " is not 100 points");
scoreAlert = true;
}
System.out.println(question.getQuestionContent() + "~" + userAnswer + "~" + isCorrect);
}
if(testPaper.getQuestionScores().size()>answers.size())
System.out.printf("answer is null\n");
for (int i = 0; i < testPaper.getQuestionScores().size(); i++) {
System.out.printf("%d", scores[i]);
if (i != testPaper.getQuestionScores().size()- 1) {
System.out.printf(" ");
}
}
System.out.printf("~%d\n", totalScore);
}
}
}
这道题在上上个星期的训练中,我并没有拿到好的成绩,主要原因还是出现在正则表达式这一知识点和在使用hashmap的时候,并不知道hashmap的线程并不安全,不能保证键和输入一一对应。现在重新回过头来分析的话,会发现暴露出来了好多问题,
- 依旧是使用的面向过程的思路来写题目的,没有更加深入地理解面向过程这一思想的深层含义
- 主函数仍存在大量代码,没有设计方法来封装这些代码
- 没有深入学习正则表达式和Java集合的使用方法,只是一知半解地去胡乱编码
-题目集3
源代码:
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
class Question {
int number;//题目编号
String content;//内容
String answer;//标准答案
public void setNumber(int number) {
this.number = number;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public Question(int number, String content, String answer) {//初始化
this.number = number;
this.content = content;
this.answer = answer;
}
public int getNumber() {
return number;//返回编号
}
}
class TestPaper {//试卷题目类
int paperNumber;//试卷编号
List
public int getPaperNumber() {
return paperNumber;
}
public void setPaperNumber(int paperNumber) {
this.paperNumber = paperNumber;
}
public void setNumberScores(List<NumberScore> numberScores) {
NumberScores = 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 int getSheetNumber() {
return sheetNumber;
}
public void setSheetNumber(int sheetNumber) {
this.sheetNumber = sheetNumber;
}
public void setStudentID(String studentID) {
this.studentID = studentID;
}
public Map<Integer, String> getAnswers() {
return answers;
}
public void setAnswers(Map<Integer, String> answers) {
this.answers = answers;
}
//////写到这里
public AnswerSheet(int SheetNumber,String studentID) {
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;
}
}
class NumberScore
{
int number;
int score;
public void setNumber(int number) {
this.number = number;
}
public void setScore(int score) {
this.score = score;
}
public NumberScore(int number, int score) {//初始化
this.number = number;
this.score= score;
}
public int getNumber()
{ return number;
}
public int getScore()
{ return score;
}
}
//正则表达式
class RegexPatterns {
public static final String QUESTION_PATTERN = "^#N:(.) #Q:(.) #A:(.*)
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List
LinkedHashMap<Integer, TestPaper> testPapers = new LinkedHashMap<>();//试卷编号——试卷
LinkedHashMap<Integer, List
LinkedHashMap<String, String> students = new LinkedHashMap<>();//学号——姓名
List
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.equals("end")) {
break;
} else if (line.startsWith("#N:")) {
String regex = RegexPatterns.QUESTION_PATTERN;
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
if(matcher.matches())
{
String[] parts = line.split("#");
String[] parts1 = parts[1].split(":");
String number = parts1[1].trim();
//System.out.println("number = " + number);
String[] parts2 = parts[2].split(":");
String content = parts2[1].replaceAll(" +","");
//System.out.println("content = " + content);
String[] parts3 = parts[3].split(":");
String[] parts4 = parts3[1].trim().split(" ");
String answer = parts4[0];
//System.out.println("answer = " + answer);
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(RegexPatterns.TEST_PATTERN);
Matcher matcherTest= patternTest.matcher(line);
if(matcherTest.find())
{
String[] parts = line.split(":");
String parts1 = parts[1].trim().replaceAll(" +","-");
// System.out.println("parts1 = " + parts1);
String[] parts2 = parts1.split("-+");
int paperNumber = Integer.parseInt(parts2[0]);
TestPaper testPaper = new TestPaper(paperNumber);
//System.out.println("paperNumber = " + paperNumber);
for (int i = 1; i < parts2.length; i+=2) {
int questionNumber = Integer.parseInt(parts2[i]);
// System.out.println("questionNumber = " + questionNumber);
int score = Integer.parseInt(parts2[i+1]);
// System.out.println("score = " + 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) {
assert false;
answer= answer.replace("","yes");
} else {
}
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 (String part : parts) {
String[] IDname = part.split(" ");
students.put(IDname[0], IDname[1]);
}
}else if (line.startsWith("#D:")) {
String line1=line.substring(3);
String[] parts = line1.split(" ");
for (String part : parts) {
String[] number = part.split("-");
deletes.add(Integer.parseInt(number[1]));
}
}else
{
System.out.println("wrong format:"+line);
}
}
//第一次循环为了打印是否为满分卷
for (int paperNumber : testPapers.keySet()) {
int totalScore = 0;//总分
TestPaper testPaper = testPapers.get(paperNumber);//创建遍历到的当前的试卷
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> questionScores = testPaper.getNumberScores().stream()
.map(NumberScore::getScore)
.collect(Collectors.toList());
List<AnswerSheet> AnswerSheets = answerSheets.get(paperNumber);
for (AnswerSheet answerSheet : AnswerSheets) {
List<Question> paperQuestions = new ArrayList<>();
int deletedQuestionNumber = 100;
for (NumberScore numberScore : testPaper.getNumberScores()) {
Question targetQuestion = questions.stream()
.filter(question -> question.getNumber() == numberScore.getNumber())
.findFirst().orElse(null);
if (targetQuestion != null) {
paperQuestions.add(targetQuestion);
} else {
paperQuestions.add(new Question(deletedQuestionNumber, "delete", "delete"));
deletedQuestionNumber++;
}
}
for (int i = 0; i < paperQuestions.size(); i++) {
Question question = paperQuestions.get(i);
String answer = (i < answerSheet.answers.size()) ? answerSheet.answers.get(i + 1): "answer is null";
if (answer.equals("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 ? "true" : "false"));
}
} else {
System.out.println("the question " + question.getNumber() + " invalid~0");
}
}
}
String studentName = students.get(answerSheet.getStudentID());
if (studentName != null) {
System.out.print(answerSheet.getStudentID() + " " + studentName + ": ");
int totalPaperScore = 0;
int questionIndex = 0;
for (int i = 0; i < paperQuestions.size(); i++) {
Question question = paperQuestions.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) {
System.out.print("0" + (questionIndex == paperQuestions.size() - 1 ? "" : " "));
} else {
totalPaperScore += questionScores.get(i);
System.out.print(questionScores.get(i) + (questionIndex == paperQuestions.size() - 1 ? "" : " "));
}
} else {
System.out.print("0" + (questionIndex == paperQuestions.size() - 1 ? "" : " "));
}
questionIndex++;
}
System.out.printf("~%d\n", totalPaperScore);
} else {
System.out.print(answerSheet.getStudentID() + " not found");
}
}
}
}
}
}
由于在编码过程中,还是用的是面向过程的思路去解决问题,导致圈复杂度比较大
这道题在上个星期的训练中,我拿了88分,最后这几个测试点一直都没有过,主要的原因还是自己对题目的意思有点曲解,我错误地以为,题目错误输入,是以第一个输入结果来保存(如果输入2 3 5,我理解为只要保存2,其他的都是错误输入),导致我一直改我的正则表达式,到最后输入答卷信息的时候,我正则表达式一直都写不出来(因为输入中的空格的原因),怎么调试都无济于事,我去问同学这个怎么处理,然后才发现是自己理解错了题目意思。
下面是我的总结
- 在稀里糊涂的理解错误题目要求的过程中,我重心转到了如何使用正则表达式的这一层面中,在不断地调试中再加上不断地查询,我更加深入地了解了正则表达式的使用。
- 上个星期,我一直在思考怎样才算得上面向过程,说实话,之前老师布置的网课任务,我一直都是没有认认真真地看,大部分时间都是把网课挂在旁边,平时上课也是听得稀里糊涂的,后面我就去重新打开了老师布置的网课任务,重新刷网课,才发现老师讲通了好多我所谓的痛点。
(3)踩坑心得
代码在提交过程中出现的问题:
- 格式问题,在源码提交的过程中,格式问题可坑苦了我,写第一次大作业的时候,经常就是出现格式错误。
- 问题考虑不全面,在依据题干信息设计的时候,没有去认真思考和设计,简单来说,就是随便看下题目就盲区地去打代码,导致问题一旦出现后,前面写的东西又要重新改,没有好好地去设计自己的代码
- 在类的设计过程中,思路相当混乱,没有缕清出各个类所要发挥的职责,就随便乱打一通,导致效率比较低下,后面又要重新去改,得不偿失。
- 正则表达式要认真设计,不要等下又重新回过头来改逻辑,在完成大作业的过程中,我有好几次就是因为正则表达式设计的不好就又重新推翻自己原有的逻辑重新打,在这里花了好多好多时间,在后面的正则表达式的设计的时候,要好好考虑可能出现的情况。
- 信息的存储方式,刚开始我是一直以为hashmap是特别好用的,所有我把全部的存储方式都变成了hashmap,后面在使用的过程中才发现,hashmap并不是我想象中的那么好用,它并不能保证线程的安全,也不能保证它能够像链表一样存储,在第二次大作业中,我是真的被这个害苦了,这让我明白了一件事,就是,以后每学习到一件新事物,都要去系统地学习,而不是一知半解就去随便使用,并和其他类似的去做对比,得出相对应的使用条件。
- 字符串的使用,字符串在Java当中,算得上是数据处理的一大利器,它的形式具有多元化,可以帮我们处理好多问题,在第二次大作业当中,我在处理数据的时候,出现好多错误,后面发现大部分都是出现在字符串的处理上,比如字符串的类型转换,刚开始我甚至不知道Java中的字符串是不能更改的,就随便地去赋值,这让我摔了个大坑。
- 空指针异常,在处理数据的时候,出现了空指针异常的情况,就是在保存数据的时候,如果用户没有输出,导致后面的存储数据处于空指针的状态下,就需要我们用if来控制空指针异常这一情况
(4)改进建议
现在自己对之前的代码总结之后,发现自己代码的问题主要出现在对面向过程这一思想还没有理解,出现了比较大的问题,在类的处理层面,没用用类去封装方法,导致在主函数中出现了冗长的代码,并且依旧还是用面向过程的思想去编码,这也是我接下来要去解决的问题。还有就是,在写题目之前,没用认真地去设计自己的代码,导致逻辑混乱。这俩个方面是我接下来需要改进的方向。
(5)总结
在前一段学习Java的过程当中,说实话,我学的真的不咋地,就是那种学得稀里糊涂的那种感觉,因为自己也没有足够重视,说白了就是没用花到时间,沉迷于游戏。现在自己沉下心来思考,才发现了自己在学习方面出现了好大的问题,问题一直都是没有及时地去解决,导致问题越积越多,学起来也一直感觉力不从心,进而让自己一直处于一种死循环里。我现在也已经意识到了问题,也准备尽可能地去弥补。还有就是,我一直都没有把那种面向对象的思维方式从面向过程那里完全走出来,思考问题方式也是这样,这是我要解决的!
老师您在授课过程中,我是觉得没问题的,觉得您讲得通俗易懂,不过,老师您能不能在课前稍微说明一下下节课您准备讲什么和我们大致所需要学习的知识点,我们才有所准备,我是有几次真的听得一头雾水,因为我不知道您到底在讲哪里,我需要在课前学习啥和我需要所具备的基础知识,我感觉这样我才能够更好地去吸收您上课所讲的知识和后面的复习总结。
本文作者:蓝文杰
本文链接:https://www.cnblogs.com/lwj1/p/18148002
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步