工程概论作业二——个人项目《论文查重程序(JAVA实现)》
工程概论 | 计算2112 |
---|---|
这个作业要求在哪里 | 工程概论作业二 |
这个作业的目标 | 熟悉GitHub的使用,编写程序实现论文查重,了解个人软件开发流程。 |
psp表格
|
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 15 | 20 |
Estimate | 估计这个任务需要多少时间 | 120 | 150 |
Development | 开发 | 60 | 60 |
Analysis | 需求分析 (包括学习新技术) | 30 | 35 |
Design Spec | 生成设计文档 | 5 | 7 |
Design Review | 设计复审 | 5 | 8 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 30 |
Design | 具体设计 | 30 | 40 |
Coding | 具体编码 | 30 | 40 |
Code Review | 代码复审 | 20 | 15 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 45 |
Reporting | 报告 | 60 | 90 |
Test Repor | 测试报告 | 15 | 20 |
Size Measurement | 计算工作量 | 5 | 5 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 10 | 7 |
合计 | 445 | 572 |
需求分析
题目:论文查重
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
算法设计
核心思路:通过计算原文和抄袭版论文的词频向量的 Jaccard 相似度来评估它们的重复率。
1.读取论文原文和抄袭版论文
从命令行参数中获取原文文件和抄袭版论文文件的绝对路径
2.构建词频向量
使用中文分词库 Jieba 对原文和抄袭版论文进行分词处理,将分词结果存储在两个集合中。
3.计算相似度
使用函数计算 Jaccard 相似度。该函数首先计算两个集合的交集大小,然后计算两个集合的并集大小,最后将交集大小除以并集大小得到 Jaccard 相似度。
4.输出结果到答案文件
将计算得到的相似度写入答案文件中。
项目结构
计算模块接口的设计与实现过程
1.类的组织
主类:负责整个算法的控制流程和调度。
分词与相似度计算类:负责对文本进行分词的功能和计算文本相似度的功能,封装了分词操作和相似度计算的方法。
文件读写类:负责处理文件的读取和写入操作,封装了文件读写的方法。
2.函数的设计与关系
SimilarityCalculator 类中的主要函数:
calculateSimilarity(originalTokens, plagiarizedTokens):接收原文和抄袭版论文的分词结果作为参数,计算它们的相似度,并返回结果。
FileHandler 类中的主要函数:
readFile(filePath):接收文件路径作为参数,读取文件内容并返回。
writeResult(filePath, similarity):接收文件路径和相似度结果作为参数,将相似度写入指定文件。
3.算法的关键和独到之处:
关键之处:算法的关键在于使用分词和词频向量的 Jaccard 相似度计算方法来评估文本的重复率。通过将文本转化为词的集合,并计算集合的交集和并集大小,从而得到相似度值。
独到之处:该算法使用了开源的中文分词库 Jieba,能够对中文文本进行准确的分词处理。此外,算法使用了面向对象的设计思想,将不同功能的操作封装在不同的类中,提高了代码的可读性和可维护性。
4.模块接口部分的性能改进
性能分析图
改进思路
1.减少文件I/O操作:
如果文件较大,读取和处理的时间会较长。可以考虑将文件读取操作放在main函数中,将读取后的内容作为参数传递给calculateJaccardSimilarity函数。
2.优化循环和数据结构:
使用HashSet存储词汇时如果词汇量非常大,查找和插入操作的性能可能会受到影响。可以考虑使用更高效的数据结构,如Trie树或基于前缀树的实现,来提高性能。
在calculateJaccardSimilarity函数中,对词汇集合的交集和并集计算使用了retainAll和addAll方法。这些方法的性能可能不够高效。可以考虑使用更高效的算法来计算交集和并集,例如使用HashMap等数据结构。
3.使用更高效的分词库:
您目前使用的是jieba分词库进行中文分词。您可以尝试其他更高效的分词库,如HanLP、Ansj等,以提高分词的速度和准确性。
计算模块部分单元测试展示
- java -jar check.jar D:\Desktop\orig.txt D:\Desktop\orig_add.txt D:\Desktop\similarity.txt
1.正常情况下两篇完全相同的论文:
原文文件:orig.txt(包含完整内容)
抄袭版论文文件:orig.txt(包含完整内容)
预期结果:相似度为1.0
2.正常情况下两篇完全不同的论文:
原文文件:orig.txt(包含完整内容)
抄袭版论文文件:other.txt(包含完全不同的内容)
预期结果:相似度为0.0
3.一文件为空:
原文文件:empty.txt
抄袭版论文文件:orig.txt(包含完整内容)
预期结果:相似度为0.0
4.一文件路径不存在:
原文文件:不存在的文件路径
抄袭版论文文件:orig.txt(包含完整内容)
预期结果:捕获并处理IOException异常
5.答案文件路径不存在:
原文文件:orig.txt(包含完整内容)
抄袭版论文文件:orig_add.txt(包含完整内容)
答案文件:不存在的文件路径
预期结果:产生该文件