工程概论第二次作业
Github仓库链接
作业要求
| 这个作业属于哪个课程 | 工程概论 |
|---|---|
| 这个作业要求在哪里 | 个人项目 |
| 这个作业的目标 | 掌握论文查重算法,学会使用PSP表格 |
需求
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
- 原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
- 抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
- 从命令行参数给出:论文原文的文件的绝对路径。
- 从命令行参数给出:抄袭版论文的文件的绝对路径。
- 从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
开发环境
语言选择:Java
使用工具:IDEA 2022.3
测试环境:Windows11 21H2
PSP表格
| *PSP2.1* | *Personal Software Process Stages* | *预估耗时(分钟)* | *实际耗时(分钟)* |
|---|---|---|---|
| Planning | 计划 | 30 | 40 |
| · Estimate | · 估计这个任务需要多少时间 | 300 | 298 |
| Development | 开发 | 160 | 175 |
| · Analysis | · 需求分析 (包括学习新技术) | 25 | 23 |
| · Design Spec | · 生成设计文档 | 15 | 17 |
| · Design Review | · 设计复审 | 6 | 4 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 6 | 6 |
| · Design | · 具体设计 | 30 | 35 |
| · Coding | · 具体编码 | 60 | 55 |
| · Code Review | · 代码复审 | 25 | 35 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 20 | 15 |
| Reporting | 报告 | 130 | 120 |
| · Test Repor | · 测试报告 | 50 | 60 |
| · Size Measurement | · 计算工作量 | 30 | 40 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 20 |
| · 合计 | 430 | 418 |
算法思路
首先使用readTextFromFile方法从文件中读取文本内容(通过FileReader类和Bufferedreader还有StringBuilder)
然后使用calculateSimhash的方法计算Simhash值,在这个方法中,我们使用一个HashMap来统计每个单词的词频,并计算每个单词的哈希值。最后根据词频和哈希值计算Simhash值
接下来计算原文和抄袭论文重复率,首先计算原文和抄袭论文的Simhash值,然后计算这两个值的海明距离,最后根据海明距离计算重复率
最后将重复率写入另一个文件
模块接口的设计与实现
调用jar包指令
java -jar main.jar d:\Users\LENOVO\Desktop\工程概论作业\第一项程序\orig.txt d:\Users\LENOVO\Desktop\工程概论作业\第一项程序\orig_add.txt d:\Users\LENOVO\Desktop\工程概论作业\第一项程序\answer.txt
涉及的引用类
| 类名 | 功能 |
|---|---|
| IO | 文件的读取和写入 |
| HashMap | 使用键対值的方式快速获取某个词的词频并进行计算简化代码 |
| BigInteger | 用于计算Simhash的值,由于Simhash的值可能非常大,因此需要BigInteger类进行大整数的运算 |
| Map | 用于存储特征索引和权重,提供快速的索引查找功能,实现Simhash算法中特殊权重的计算和累加 |
| 类名 | 功能 |
|---|---|
| SimHashPlagiarismChecker | 实现测试,readTextFromFile(文件读取内容),calculateWordHash(计算分词的哈希值),calculateSimhash(计算SimHash值),calculateHaiMingDistance(计算海明距离),写入文件(writeResultToFile) |
流程图

性能分析
这个性能还可以不知道该如何改进
性能分析图:

测试
部分单元测试代码
public class SimHashPlagiarismChecker {
public static void main(String []args){
String originalFile = "d:\\Users\\LENOVO\\Desktop\\工程概论作业\\第一项程序\\orig.txt";
String original_addFile = "d:\\Users\\LENOVO\\Desktop\\工程概论作业\\第一项程序\\orig_add.txt";
String answerFile = "d:\\Users\\LENOVO\\Desktop\\工程概论作业\\第一项程序\\answer.txt";
try{
String originalText = readTextFromFile(originalFile);
String original_addText = readTextFromFile(original_addFile);
double similarity = calculateSimilarity(originalText,original_addText);
writeResultToFile(answerFile,similarity);
}catch(IOException e){
e.printStackTrace();
}
}
测试数据(相似)

测试结果

测试数据(相同)

测试结果

测试数据

测试结果

代码覆盖率:

异常处理:
文件路径不存在
public static void main(String []args){
String originalFile = "d:\\Users\\LENOVO\\Desktop\\工程概论作业\\第一项程序\\ori.txt";
String original_addFile = "d:\\Users\\LENOVO\\Desktop\\工程概论作业\\第一项程序\\orig_add.txt";
String answerFile = "d:\\Users\\LENOVO\\Desktop\\工程概论作业\\第一项程序\\answer.txt";
try{
String originalText = readTextFromFile(originalFile);
String original_addText = readTextFromFile(original_addFile);
double similarity = calculateSimilarity(originalText,original_addText);
writeResultToFile(answerFile,similarity);
}catch(IOException e){
e.printStackTrace();
}
}
