軟件工程 | <網工1934> |
---|---|
作業要求: 1.在 Github 倉庫中新建一個學號為名的文件夾。 2.在開始實現程序之前,在 PSP 表格記錄下你估計在程序開發各個步驟上耗費的時間,在實現程序之后,在PSP表格記錄下你在程序的各個模塊上實際花費的時間。 3.語言不限,並將編譯好的程序發布到 Github 倉庫中的 releases 中。 4.提交的代碼要求經過 Code Quality Analysis 工具的分析並消除所有的警告。 5.完成項目的首個版本之后,請使用性能分析工具Studio Profiling Tools來找出代碼中的性能瓶頸並進行改進。 6.使用Github來管理源代碼和測試用例,代碼有進展即簽入Github。 7.使用單元測試對項目進行測試,並使用插件查看測試分支覆蓋率等指標;寫出至少10個測試用例確保你的程序能夠正確處理各種情況。 |
<作業要求> |
作業的目標: 設計一個論文查重算法,給出一個原文文件和一個在這份原文上經過了增刪改的抄襲版論文的文件,在答案文件中輸出其重復率。 |
1. PSP表格
*PSP2.1* | *Personal Software Process Stages* | *預估耗時(分鍾)* | *實際耗時(分鍾)* |
---|---|---|---|
Planning | 計划 | ||
· Estimate | · 估計這個任務需要多少時間 | 1210 | 1590 |
Development | 開發 | ||
· Analysis | · 需求分析 (包括學習新技術) | 300 | 420 |
· Design Spec | · 生成設計文檔 | 120 | 100 |
· Design Review | · 設計復審 | 40 | 20 |
· Coding Standard | · 代碼規范 (為目前的開發制定合適的規范) | 40 | 20 |
· Design | · 具體設計 | 200 | 300 |
· Coding | · 具體編碼 | 300 | 420 |
· Code Review | · 代碼復審 | 100 | 60 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 100 | 180 |
Reporting | 報告 | ||
· Test Repor | · 測試報告 | 30 | 20 |
· Size Measurement | · 計算工作量 | 30 | 20 |
· Postmortem & Process Improvement Plan | · 事后總結, 並提出過程改進計划 | 50 | 30 |
· 合計 | 1210 | 1590 |
2. 計算模塊接口與實現過程
2.1 程序實現類
主類:
Application ,包含main方法,可以接收指定參數,傳遞給Document類進行文件的輸入輸出,並調用其他工具類中的方法實現程序的運行。
工具類:
CuttingWordsUtil,中文工具類,具有中文分詞的方法。
DocumentUtil,文件工具類,控制文件的輸入輸出。
SimpleCommonWords,簡單共有詞計算類,通過簡單共有詞算法對兩個文檔的相似度進行計算。
測試類:
TestCoverage,測試各模塊的功能是否正常。
項目結構:
項目流程:
2.2 關鍵函數的分析與實現
實現查重的關鍵點在於分詞函數和相似度算法
在開始編寫程序前,查詢了很多關於分詞器和相似度算法的資料,參考了以下文章
中文分詞器的基本原理和簡單實現
11大Java開源中文分詞器的使用方法和分詞效果對比
文本相似度算法
Java分布式中文分詞組件 - word分詞
經過考慮后,選擇word分詞器和簡單共有詞算法來完成本次設計。
簡單共有詞算法簡單流程如下:
String1: 我讀過那么多故事。
String2: 我聽過那么多故事。
1) 分詞
String1: [我, 讀過, 那么多, 故事]
String2: [我, 聽過, 那么多, 故事]
2) 分別計算總字符數
words1 = 4
words2 = 4
3) 計算共有詞的總字符
commonwords = 3
4) 計算相似度
選取長度最長的字符數為分母,共有詞的總字符為分子
result = 3 / 4 = 0.75
這個算法的思路比較直觀,易於理解其基本原理,直觀的講就是首先統計需要比較相似度的兩篇文檔的總字數,其次分別統計文檔中共有詞語的總字符數,第三用共有詞語除以最長文檔的字數得到相似度衡量的數值。
3. 計算模塊接口部分的性能改進
第一版程序耗時相當多,需要將近40秒的運行時間
經過研究后發現是由於分詞器自帶的控制台輸出日志占用的時間太多了,於是進行了改進
第二版程序,將依賴中的分詞器版本下調到1.2,運行速度明顯提升很多
可以看出占用最多的是分詞器查詢字典函數調用
但是日志輸出還是耗費了很多時間,於是又去尋找禁用日志輸出的方法
第三版禁用了日志輸出,輸出時間再次減少
4. 計算模塊部分單元測試展示
4.1 CuttingWordsUtil類測試
測試結果:
可以看出,word分詞器可以識別一些特殊符號並同樣划分出來
4.2 SimpleCommonWords類測試
測試結果:
當兩個句子為空串時,輸出為NaN,需要做異常處理
4.3 代碼覆蓋率
5. 模塊部分異常處理說明
在單元測試模塊中可以知道,當兩個字符串為空串時輸出NaN,需要進行異常處理
在Application類中添加判斷,如果都為空則輸出提示信息並結束程序
6. 項目程序功能測試
當原文件和抄襲論文文件為UTF-8編碼格式時測試代碼為:
java -Dfile.encoding=utf-8 -jar PaperCheck.jar D:\tests\orig.txt D:\tests\orig_0.8_dis_10.txt D:\tests\result1.txt
當原文件和抄襲論文文件為ANSI編碼格式時測試代碼為:
java -jar PaperCheck.jar D:\tests\orig.txt D:\tests\orig_0.8_dis_10.txt D:\tests\result1.txt
此處的SLF4J提示為禁用日志輸出的結果,不影響程序正常運行
運行結果文件: