第一次个人编程作业

GitHub仓库链接:https://github.com/Sleepy-li/3224004192

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class56-Grade2024-CS
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class56-Grade2024-CS/homework/15693
这个作业的目标 写一个论文查重算法

image

PSP2.1 Personal Software Process Stages 预估耗时(分钟)
Planning 计划 300
· Estimate · 估计这个任务需要多少时间 300
Development 开发 305
· Analysis · 需求分析 (包括学习新技术) 45
· Design Spec · 生成设计文档 15
· Design Spec · 设计复审 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30
· Design · 具体设计 30
· Coding · 具体编码 120
· Code Review · 代码复审 20
· Test · 测试(自我测试,修改代码,提交修改) 15
Reporting 报告 70
· Test Repor · 测试报告 20
· Size Measurement · 计算工作量 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30
· 合计 375

计算模块接口的设计与实现过程:
1、代码组织,类与函数关系
该项目一共有4个Java类文件,分别是:
(1)SimHash类(核心算法):
作用:实现文本清洗、2-gram分词、simhash指纹计算、相似度计算。

  • cleanText(String text):文本清洗,过滤多余符号、空格,保留中文;返回清洗后的干净字符串。
  • computeSimHash(String text):2‑gram 滑动窗口,生成 64 位 SimHash long 指纹。
  • calcSimilarity(long hash1, long hash2):计算两个指纹海明距离,换算得到 0‑1 之间文本相似度。

(2)FileUtil类(文件工具类):
作用:负责磁盘文件读写。

  • readFile(String path):读取文本文件,读取失败返回 null。
  • writeFile(String path, double rate):将相似度保留两位小数写入输出文件。

(3)PaperCheckMain类(程序入口主类):
作用:命令行程序入口,接受3个命令行参数:原文路径、待检测文本路径、输出结果路径;串联文本读取-文本清洗-simhash计算-结果写入全流程。

(4)SimhashTest类(JUnit单元测试类):
作用:对SimHash全部接口做单元测试,覆盖正常文本、空字符串、短文本、无关文本等边界场景。

调用流程:PaperCheckMain调用FileUtil读取两个文本 → 调用SimHash.cleanText()清洗文本 → 调用computeSimHash()生成两个 64 位指纹 → calcSimilarity()计算相似度 → FileUtil.writeFile()输出结果。

2、算法关键与独到之处

  • 采用中文2-gram双字符滑动窗口做分词,不再使用单字符。中文语义依赖相邻汉字,2‑gram 可以抵抗字符调换、局部改写、少量增删,对于作业的dis字符打乱测试集鲁棒性更强。
  • 64 位 long 存储 simhash 指纹,计算海明距离直接位运算,运算效率高。
  • 边界兼容:处理输入空字符串;当文本长度不足 2,自动退化为单字符统计权重,避免数组越界异常。
  • 输出约束:相似度强制保留两位小数,输出文件只输出纯数字,无多余提示文字,满足作业命令行输出规范。

计算模块接口部分的性能改进:

计算模块部分单元测试展示:
单元测试覆盖率截图如下图所示,使用 EclEmma 工具采集代码覆盖率。
核心类SimHash.java行覆盖率 77.5%,FileUtil.java行覆盖率 85.7%,PaperCheckMain.java行覆盖率 77.8%。
单元测试覆盖空文本、短文本、完全相同文本、无关文本等边界场景,覆盖 SimHash 算法核心函数cleanText()computeSimHash()calcSimilarity(),保证算法模块逻辑正确性。
未覆盖代码主要是主类中文件读取失败、命令行参数异常的分支,这些属于 IO 异常分支,可单独构造用例触发。

image

计算模块部分异常处理说明:

异常场景 设计目标 对应处理逻辑 单元测试思路
文件路径错误、文件不存在 捕获读取文件异常,程序不直接崩溃,控制台打印错误提示 FileUtil.readFile 捕获 IO 异常,返回 null;主类判断如果返回 null,打印 “读取文件失败” 直接 return 结束程序,不继续执行 simhash 计算 单元测试传入不存在的文件路径,验证返回 null
命令行传入参数数量不等于 3 防止用户命令行参数传错,程序友好提示用法 PaperCheckMain 判断args.length !=3,打印使用提示,return 退出 单元测试模拟 args 长度为 2,验证输出提示
输出目录没有写入权限,写文件失败 文件写入失败不抛出崩溃,控制台提示写入失败 FileUtil.writeFile 捕获 IO 异常,返回 boolean;主类接收返回值,打印写入失败提示 单元测试传入无权限路径,验证返回 false
输入文本为空字符串 空文本不产生数组越界,算法可以正常返回指纹 computeSimHash 增加文本长度判断,文本不足 2 字符退化为单字符处理 test5OneEmpty 单元测试,输入空字符串
测试组合 输出相似度
orig.txt vs orig.txt 1.00
orig.txt vs orig_0.8_add.txt 0.98
orig.txt vs orig_0.8_del.txt 0.83
orig.txt vs orig_0.8_dis_1.txt 0.83
orig.txt vs orig_0.8_dis_10.txt 0.83
orig.txt vs orig_0.8_dis_15.txt 0.83

最后的PSP表格:

PSP2.1 Personal Software Process Stages 实际耗时(分钟)
Planning 计划 300
· Estimate · 估计这个任务需要多少时间 300
Development 开发 415
· Analysis · 需求分析 (包括学习新技术) 45
· Design Spec · 生成设计文档 20
· Design Spec · 设计复审 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 60
· Design · 具体设计 60
· Coding · 具体编码 120
· Code Review · 代码复审 35
· Test · 测试(自我测试,修改代码,提交修改) 45
Reporting 报告 125
· Test Repor · 测试报告 60
· Size Measurement · 计算工作量 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 45
· 合计 540
posted @ 2026-09-15 22:05  李海婷  阅读(8)  评论(0)    收藏  举报