软工作业2:个人项目-论文查重
github链接:github
| 这个作业属于哪个课程 | 计科21级12班 - 广东工业大学 |
|---|---|
| 这个作业要求在哪里 | 作业要求 |
| 这个作业的目标 | 完成个人项目-论文查重;学会写单元测试 |
一、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 - 编程语言:
jdk1.8
2.2 开发工具
- maven包管理工具
- ide:
IDEA2022.3.1 - 性能分析工具:Jprofiler11.1.4
2.3 项目依赖
- junit测试框架
- jieba-java中文分词库
2.4 算法设计说明
- 采用余弦相似度与jaccard相似度判断文章相似度
- 基于tf算法的余弦相似度:
- 分词后计算每个词的词频(将其视为一个向量)
- 计算向量内积
- 计算对应文本分词词频数组的范数
- 最后用向量内积除以范数的乘积得到结果
- jaccard相似度:
- 分词后使用set集合接收结果
- 计算两个文本的交集和并集
- 最后用交集数量除以并集数量得到结果
- 根据权重计算最终结果:
- 项目中,我设置余弦相似度的权重为0.6;jaccard相似度的权重为0.4
最终结果 = 余弦相似度 * 0.6 + jaccard相似度 * 0.4
2.5 接口设计与实现过程

-
Main类作为程序接口,有以下功能:
- 接收命令行参数并检查合法性
- 调用
DuplicateCheckService接口
-
service包有以下内容:
-
定义
DuplicationChcekService接口 -
定义
DuplicationCheckServiceImpl类实现DuplicationChcekService接口实现内容包括:
- 调用FileUtils读取文本内容和输出结果到本文中
- 调用SeparateWordUtils对内容进行分词以及计算词频
- 计算Jaccard相似度
- 调用TfUtils计算余弦相似度
- 最后根据两个相似度的权重计算最终结果
-
-
utils包有以下内容:
- 定义
FileUtils类,用于读取文件文本和输出内容到文本 - 定义
SeparateWordUtils类,读取stop_words.txt用于过滤特殊符号和标点符号,并且用于分词 - 定义
TfUtils类,用于计算余弦相似度
- 定义
-
rescources的内容:设置
stop_words.txt管理要分词时要过滤的内容
三、测试与性能分析
3.1 测试
-
DuplicationCheckService测试-
代码如下:
@Test public void duplicationCheckTest() throws IOException { String origin = "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig.txt"; String output = "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\result.txt"; String[] targetFiles = { "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig_0.8_add.txt", "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig_0.8_del.txt", "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig_0.8_dis_1.txt", "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig_0.8_dis_10.txt", "D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig_0.8_dis_15.txt" }; // 调用duplicateCheckService接口 for (String target:targetFiles) { double result = duplicateCheckService.duplicateCheck(origin,target,output); System.out.printf("[%tc] %s 该文件查重率为%.2f \n",new Date(),target,result); } } -
覆盖率如下:

-
测试结果如下:

-
-
SeparateWordUtils测试-
测试代码如下:
@Test public void testSeparateWord() throws IOException { // 读取文件 String content = FileUtils.getFileText("D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig.txt"); // 调用分词工具类 Map<String, Integer> map = separateWordUtils.separateWord(content); // 打印 map.forEach((k,v)-> System.out.printf("[%s]: %d次\n",k,v)); } -
覆盖率如下:

-
测试结果如下:

-
-
TfUtils测试-
测试代码如下:
@Test public void testCalculateCosineSimilarity() throws IOException { // 读取文件 String content1 = FileUtils.getFileText("D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig.txt"); // 读取文件 String content2 = FileUtils.getFileText("D:\\school-3\\软件工程\\gdut-software-engineering\\3121004869\\duplicate-check\\src\\test\\resources\\orig_0.8_add.txt"); Map<String, Integer> map1 = separateWordUtils.separateWord(content1); Map<String, Integer> map2 = separateWordUtils.separateWord(content2); // 调用 double v = tfUtils.calculateCosineSimilarity(map1, map2); System.out.printf("结果为%.2f\n",v); } -
覆盖率如下:

-
测试结果如下:

-
3.2 性能分析
- Override

2.Memory

四、异常说明
-
命令行参数个数错误

-
命令行参数合法性错误

-
文件读取输出错误
