軟工第二次作業

Rawven發表於2024-09-11

軟工作業2:個人專案-論文查重

GitHub連結: github

課程資訊

  • 課程: 計科22級2班 - 廣東工業大學
  • 作業要求: 作業要求
  • 目標: 完成個人專案-論文查重;學會寫單元測試

一、PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 60 30
Estimate 估計這個任務需要多少時間 30 60
Development 開發 300 420
Analysis 需求分析 (包括學習新技術) 60 30
Design Spec 生成設計文件 60 60
Design Review 設計複審 15 10
Coding Standard 程式碼規範 15 10
Design 具體設計 30 60
Coding 具體編碼 30 60
Code Review 程式碼複審 15 10
Test 測試(自我測試,修改程式碼,提交修改) 15 60
Reporting 報告 60 120
Test Report 測試報告 30 60
Size Measurement 計算工作量 10 10
Postmortem & Process Improvement Plan 事後總結, 並提出過程改進計劃 10 20
合計 740 1020

二、設計與開發

編碼規範

  • 阿里巴巴開發規範外掛

2.1 開發環境

  • 作業系統: Windows
  • 程式語言: JDK 1.8

2.2 開發工具

  • Maven包管理工具
  • IDE: IDEA 2022.3.1
  • 效能分析工具: JProfiler 11.1.4

2.3 專案依賴

  • JUnit測試框架
  • Jieba-Java中文分詞庫

2.4 演算法設計說明

longestCommonSubsequence (LCS) 演算法

  • 動態規劃

    • 使用動態規劃來計算 LCS。建立一個二維陣列 dp,其中 dp[i][j] 表示前 i 個字元和前 j 個字元的 LCS 長度。
    • 遍歷兩個字串的每個字元:
      • 如果字元相同,則 LCS 長度為 dp[i-1][j-1] + 1
      • 如果字元不同,則 LCS 長度為 Math.max(dp[i-1][j], dp[i][j-1]),即取左邊或上邊的最大值。
  • 時間複雜度

    • LCS 演算法的時間複雜度為 O(m × n),其中 m 和 n 分別是兩個字串的長度。
  • 空間複雜度

    • 空間複雜度為 O(m × n),用於儲存動態規劃表。如果需要最佳化空間,可以只保留當前行和上一行的資料。
  • 優點

    • LCS 演算法簡單直觀,適合用於文字相似度檢測。
    • 結果能夠有效反映文字之間的相似性。
  • 缺點

    • 對於較長的文字,計算複雜度較高,可能導致效能問題。
    • 僅依賴於字元匹配,無法捕捉文字的語義資訊。

2.5 介面設計與實現過程

類設計與實現過程

1. 檔案處理類 (FileHandler)

設計目的

FileHandler 類的主要目的是封裝檔案操作,以便於讀取和寫入文字檔案。透過將檔案操作集中在一個類中,程式碼變得更加模組化,便於維護和重用。

實現過程

  • 讀取檔案

    • 使用 Files.readAllBytes 方法讀取檔案內容,並轉換為字串。
    • 處理可能的 IOException,確保檔案讀取的安全性。
  • 寫入檔案

    • 使用 Files.writeString 方法將內容寫入檔案。新增了 StandardOpenOption.APPEND 選項以確保內容被追加,而不是覆蓋。
    • 新增換行符,確保每次追加內容都在新的一行開始。

2. 相似度計算類 (SimilarityCalculator)

設計目的

SimilarityCalculator 類專注於計算文字之間的相似度,主要採用最長公共子序列(LCS)演算法。將相似度計算邏輯與檔案處理分開,有助於清晰地劃分責任。

實現過程

  • 計算相似度

    • 定義 calculateSimilarity 方法,接收兩個字串引數(原始文字和抄襲文字)。
    • 呼叫 longestCommonSubsequence 方法計算 LCS 長度。
    • 使用公式計算相似度,並透過 DecimalFormat 確保結果保留兩位小數。
  • LCS 演算法實現

    • 使用兩個一維陣列 prevcurr,將空間複雜度最佳化為 O(n)
    • 透過動態規劃遍歷兩個字串,更新陣列以計算 LCS 長度。

主程式類 (PaperCheck)

設計目的

PaperCheck 類作為程式的入口,負責協調檔案處理和相似度計算的工作。它整合了其他兩個類,形成完整的程式。

實現過程

  • 主方法
    • main 方法中建立 FileHandlerSimilarityCalculator 的例項。
    • 呼叫 FileHandlerreadFile 方法讀取原始文字和抄襲文字。
    • 呼叫 SimilarityCalculatorcalculateSimilarity 方法計算相似度。
    • 將相似度結果格式化並寫入輸出檔案,同時列印到控制檯。

三、測試與效能分析

3.1 測試

LCE演算法最佳化:

-之前的實現:使用了一個二維陣列 dp,其大小為 m x n,其中 m 和 n 是兩個字串的長度。這在處理較大字串時,會佔用大量記憶體。
-最佳化後的實現:只使用兩個一維陣列prev和curr,分別儲存當前行和上一行的狀態。這樣,空間複雜度從O(m*n)降低到O(n),顯著減少了記憶體使用。
執行時JProfiler分析

覆蓋率

部分測試樣例:測試LCS演算法實現,主要透過正常引數和空引數進行測試

可能的異常

命令列引數不規則

直接判斷處理

文字檔案為空

直接判斷然後結束程式

相關文章