JAVA學習第一次Blog

李昱成發表於2024-04-21

前段時間老師在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 answers;
private List results;

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 answers = new ArrayList<>();

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 questionScores;

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 answers;

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 questions;
private List testPapers;
private List students;
private List answerSheets;
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)分數設定均勻一些,現在的大作業前面題目就算寫出來了也就小几十分,最後一題沒寫出來就是直接七八十分沒了。

相關文章