前段時間老師在PTA上釋出了三次大作業,這幾次大作業的難度都比較高,對我來說除了前面的題目,最後的大分數壓軸題我每次都做不出來。
這與上個學期學的C語言作業難度簡直不是一個等級的,不過JAVA老師也在上課期間一直強調,“我們JAVA課程一定要做出改變,不能說怕學生掛科就把難度設定的很低,這樣是起不到學習的作用的“。
上個學期學的C語言感覺就是程式碼行數不多,邏輯就會比較清晰,流程很線性,一步步來,構建相應的函式,呼叫關係,就可以比較輕鬆的解決問題。
但是,這一套顯然在JAVA身上不好用,JAVA是物件導向的語言,而C語言是程序導向的。這兩種語言從根本上就有著天差地別的區別。也許就是這種思考問題的差異化,導致我做題目感到異常困難。
當然,畢竟是自己的專業課,再困難也要努力克服。
下面我會逐一分析前幾次的大作業題目,分析自己學習過程中的錯誤並吸取經驗教訓。
第一次大作業:
1:設計一個風扇Fan類 這個比較簡單,就是初步認識一下JAVA的題目,用到了get set 方法。沒什麼分析的。
2:建立一個類Student,和上面的題目同理。
3:建立學生類,包含
屬性:學號(String)、姓名(String)、語文成績(int)、數學成績(int)、物理成績(int) 同理。
4:成績計算-2-關聯類 這一題開始有一定的難度了,第一次出現了關聯類,一道題目不止一個類了,並且各種類之間還有相互關係。這一題開始把我難住了一會兒,不過仔細想想,也就是一道題裡多寫幾個類而已,然後搞清楚每個類裡面有什麼屬性和方法就行了,也不算太難。
5:第五題,最難的一題來了,見到題目的第一眼,我就看到了長長的題目,很多要求,而且還要使用三個類。這一題我可以說是想了很久。
題目:設計實現答題程式,模擬一個小型的測試,要求輸入題目資訊和答題資訊,根據輸入題目資訊中的標準答案判斷答題的結果。
輸入格式:
程式輸入資訊分三部分:
1、題目數量
格式:整數數值,若超過1位最高位不能為0,
樣例:34
2、題目內容
一行為一道題,可以輸入多行資料。
格式:"#N:"+題號+" "+"#Q:"+題目內容+" "#A:"+標準答案
格式約束:題目的輸入順序與題號不相關,不一定按題號順序從小到大輸入。
樣例:#N:1 #Q:1+1= #A:2
#N:2 #Q:2+2= #A:4
3、答題資訊
答題資訊按行輸入,每一行為一組答案,每組答案包含第2部分所有題目的解題答案,答案的順序號與題目題號相對應。
格式:"#A:"+答案內容
格式約束:答案數量與第2部分題目的數量相同,答案之間以英文空格分隔。
樣例:#A:2 #A:78
2是題號為1的題目的答案
78是題號為2的題目的答案
答題資訊以一行"end"標記結束,"end"之後的資訊忽略。
輸出格式:
1、題目數量
格式:整數數值,若超過1位最高位不能為0,
樣例:34
2、答題資訊
一行為一道題的答題資訊,根據題目的數量輸出多行資料。
格式:題目內容+" ~"+答案
樣例:1+1=~2
2+2= ~4
3、判題資訊
判題資訊為一行資料,一條答題記錄每個答案的判斷結果,答案的先後順序與題目題號相對應。
格式:判題結果+" "+判題結果
格式約束:
1、判題結果輸出只能是true或者false,
2、判題資訊的順序與輸入答題資訊中的順序相同
樣例:true false true
除此之外還需要用到三個類:
題目類(用於封裝單個題目的資訊):
屬性:題目編號、題目內容、標準答案-standardAnswer
方法:資料讀寫set\get方法、
判題方法(答案-answer):判斷答案-answer是否符合標準答案-standardAnswer
試卷類(用於封裝整套題目的資訊)
屬性:題目列表(題目類的物件集合)、題目數量
方法:判題方法(題號-num、答案-answer):判斷答案-answer是否符合對應題號的題目標準答案-standardAnswer
儲存題目(題號-num、題目-question):將題目儲存到題目列表中,儲存位置與num要能對應
答卷類(用於封裝答題資訊)
屬性:試卷(試卷類的物件)、答案列表(儲存每一題的答案)、判題列表(儲存每一題的判題結果true/false)
方法:判題方法(題號-num):判斷答案列表中第num題的結果是否符合試卷中對應題號的題目標準答案
輸出方法(題號-num):按照題目的格式要求,輸出題號為num的題目的內容和答題結果。
儲存一個答案(題號-num,答案-answer):儲存題號為num的題目的答題結果answer。
我的答案:
我設計的題目類:
`class Question {
private int number;
private String content;
private String standardAnswer;
public Question(int number, String content, String standardAnswer) {
this.number = number;
this.content = content;
this.standardAnswer = standardAnswer;
}
public int getNumber() {
return number;
}
public String getContent() {
return content;
}
public String getStandardAnswer() {
return standardAnswer;
}
public boolean isCorrect(String answer) {
return standardAnswer.equals(answer);
}
}包含題目號,內容,答案屬性。get set方法,判斷方法。 然後是試卷類:
class Exam {
private Map<Integer, Question> questions;
private int questionCount;
public Exam() {
questions = new HashMap<>();
questionCount = 0;
}
public void addQuestion(Question question) {
questions.put(question.getNumber(), question);
questionCount++;
}
public boolean checkAnswer(int number, String answer) {
Question question = questions.get(number);
if (question != null) {
return question.isCorrect(answer);
}
return false;
}
public int getQuestionCount() {
return questionCount;
}
public List<Question> getQuestions() {
return new ArrayList<>(questions.values());
}
}用到了HashMap,判讀題號和答案,儲存題目的方法。 然後是答卷類:
class AnswerSheet {
private Exam exam;
private List
private List
public AnswerSheet(Exam exam) {
this.exam = exam;
this.answers = new ArrayList<>();
this.results = new ArrayList<>();
}
public void addAnswer(String answer) {
answers.add(answer);
}
public void evaluateAnswers() {
for (int i = 0; i < answers.size(); i++) {
results.add(exam.checkAnswer(i + 1, answers.get(i)));
}
}
public void printAnswersAndResults() {
List<Question> questions = exam.getQuestions();
for (int i = 0; i < questions.size(); i++) {
System.out.println(questions.get(i).getContent() + " ~" + answers.get(i));
}
for (boolean result : results) {
System.out.print(result ? "true" : "false" + " ");
}
System.out.println();
}
}`
這裡用到了List。
可能是因為對List和HashMap不夠理解,導致在最後一題大作業卡了好久,程式一直報錯,一直不能輸出想要的結果。無奈提交時間已經到了,只能放棄。
第二次大作業:
前三題比較簡單,在此就不分析了。
依然是來到大作業的最後一題,這一題是在第一次題目的基礎上增加功能。比如:程式輸入資訊分三種,三種資訊可能會打亂順序混合輸入;試卷總分警示該部分僅當一張試卷的總分分值不等於100分時作提示之用,試卷依然屬於正常試卷,可用於後面的答題。如果總分等於100分,該部分忽略,不輸出。因為第一次大作業最後一題沒能做出來,導致第二次修改增加功能也沒法做,再加上那段時間C語言的課設馬上就要提交了,導致第二次大作業也沒能完成。
但總體還是有一些修改的:class Question {
String id;
String content;
String answer;
public Question(String id, String content, String answer) {
this.id = id;
this.content = content;
this.answer = answer;
}
}
class TestPaper {
String id;
Map<String, Integer> questionsAndScores = new HashMap<>();
public TestPaper(String id) {
this.id = id;
}
public void addQuestion(String questionId, int score) {
questionsAndScores.put(questionId, score);
}
}
class AnswerSheet {
String testPaperId;
List
public AnswerSheet(String testPaperId) {
this.testPaperId = testPaperId;
}
public void addAnswer(String answer) {
answers.add(answer);
}
}
這次是換了一種風格,將主要內容寫在Main類的main方法裡,想以此當作C語言寫,但是老師說不能再以程序導向的方式寫了,所以我只能收手。
第三次大作業:
前面兩題略過,看到最後一題,發現又是前兩次大作業的升級版。
題目相比之前的大作業增加了:學生資訊、刪除題目資訊。
這一次我改進了程式碼:`import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
class Question {
private int id;
private String content;
private String answer;
public Question(int id, String content, String answer) {
this.id = id;
this.content = content;
this.answer = answer;
}
public int getId() {
return id;
}
public String getContent() {
return content;
}
public String getAnswer() {
return answer;
}
public String toString() {
return "Question{" +
"id=" + id +
", content='" + content + '\'' +
", answer='" + answer + '\'' +
'}';
}
}
class TestPaper {
private int id;
private List
public TestPaper(int id) {
this.id = id;
this.questionScores = new ArrayList<>();
}
public int getId() {
return id;
}
public List<QuestionScore> getQuestionScores() {
return questionScores;
}
public void addQuestionScore(QuestionScore questionScore) {
questionScores.add(questionScore);
}
public String toString() {
return "TestPaper{" +
"id=" + id +
", questionScores=" + questionScores +
'}';
}
}
class QuestionScore {
private int questionId;
private int score;
public QuestionScore(int questionId, int score) {
this.questionId = questionId;
this.score = score;
}
public int getQuestionId() {
return questionId;
}
public int getScore() {
return score;
}
public String toString() {
return "QuestionScore{" +
"questionId=" + questionId +
", score=" + score +
'}';
}
}
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 String getName() {
return name;
}
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
class AnswerSheet {
private int testPaperId;
private String studentId;
private List
public AnswerSheet(int testPaperId, String studentId) {
this.testPaperId = testPaperId;
this.studentId = studentId;
this.answers = new ArrayList<>();
}
public int getTestPaperId() {
return testPaperId;
}
public String getStudentId() {
return studentId;
}
public List<Answer> getAnswers() {
return answers;
}
public void addAnswer(Answer answer) {
answers.add(answer);
}
public String toString() {
return "AnswerSheet{" +
"testPaperId=" + testPaperId +
", studentId='" + studentId + '\'' +
", answers=" + answers +
'}';
}
}
class Answer {
private int questionOrder;
private String answer;
public Answer(int questionOrder, String answer) {
this.questionOrder = questionOrder;
this.answer = answer;
}
public int getQuestionOrder() {
return questionOrder;
}
public String getAnswer() {
return answer;
}
public String toString() {
return "Answer{" +
"questionOrder=" + questionOrder +
", answer='" + answer + '\'' +
'}';
}
}
public class Main{
private List
private List
private List
private List
private Map<Integer, Question> questionMap;
private Map<Integer, TestPaper> testPaperMap;
private Map<String, Student> studentMap;
public Main() {
questions = new ArrayList<>();
testPapers = new ArrayList<>();
students = new ArrayList<>();
answerSheets = new ArrayList<>();
questionMap = new HashMap<>();
testPaperMap = new HashMap<>();
studentMap = new HashMap<>();
}
public void start() {
Scanner scanner = new Scanner(System.in);
while (true) {
String input = scanner.nextLine();
if (input.equalsIgnoreCase("end")) {
break;
}
handleInput(input);
}
scanner.close();
outputResult();
}
private void handleInput(String input) {
String[] parts = input.split("\\s+");
String command = parts[0];
switch (command) {
case "#N:":
handleQuestion(input);
break;
case "#T:":
handleTestPaper(input);
break;
case "#X:":
handleStudent(input);
break;
case "#S:":
handleAnswerSheet(input);
break;
case "#D:":
handleDeleteQuestion(input);
break;
default:
System.out.println("wrong format: " + input);
}
}
private void handleQuestion(String input) {
String[] parts = input.split("\\s+");
int id = Integer.parseInt(parts[1].substring(2));
String content = parts[3].substring(1, parts[3].length() - 1);
String answer = parts[5].substring(1, parts[5].length() - 1);
Question question = new Question(id, content, answer);
questions.add(question);
questionMap.put(id, question);
}
private void handleTestPaper(String input) {
String[] parts = input.split("\\s+");
int id = Integer.parseInt(parts[1].substring(2));
TestPaper testPaper = new TestPaper(id);
for (int i = 3; i < parts.length; i += 2) {
int questionId = Integer.parseInt(parts[i].substring(0, parts[i].length() - 1));
int score = Integer.parseInt(parts[i + 1]);
QuestionScore questionScore = new QuestionScore(questionId, score);
testPaper.addQuestionScore(questionScore);
}
testPapers.add(testPaper);
testPaperMap.put(id, testPaper);
}
private void handleStudent(String input) {
String[] parts = input.split("\\s+");
String id = parts[1];
String name = parts[3];
Student student = new Student(id, name);
students.add(student);
studentMap.put(id, student);
}
private void handleAnswerSheet(String input) {
String[] parts = input.split("\\s+");
int testPaperId = Integer.parseInt(parts[1].substring(2));
String studentId = parts[3];
AnswerSheet answerSheet = new AnswerSheet(testPaperId, studentId);
for (int i = 5; i < parts.length; i += 2) {
int questionOrder = Integer.parseInt(parts[i].substring(0, parts[i].length() - 1));
String answer = parts[i + 1].substring(1, parts[i + 1].length() - 1);
Answer answerObj = new Answer(questionOrder, answer);
answerSheet.addAnswer(answerObj);
}
answerSheets.add(answerSheet);
}
private void handleDeleteQuestion(String input) {
String[] parts = input.split("\\s+");
int id = Integer.parseInt(parts[1].substring(2));
questions.remove(questionMap.get(id));
questionMap.remove(id);
}
}`
但是不知道為何報錯:Main.java:208: error: cannot find symbol
outputResult();
^
symbol: method outputResult()
location: class Main
1 error
就這樣,三次大作業最後一題都沒能寫出來,但是最後一題的分數又異常的高,導致我雖然寫出了不少題目,但就是因為沒能寫出最後一題(最後一題爆錯沒分),導致分數異常的低,還是比較可惜的。
從前面三次大作業來看,我深刻認識到了大作業的難度,也明白了不能一上學期那種懶散的態度對待JAVA課程了。對於之後的大作業,我必須打起十二分的精神,抽出足夠的時間認真研究最後一題。
對大作業機制的改進建議:(1)每一題的難度平均一些,現在的大作業前面的題目太簡單但是最後一題又太難。(2)分數設定均勻一些,現在的大作業前面題目就算寫出來了也就小几十分,最後一題沒寫出來就是直接七八十分沒了。