第一次个人编程作业
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229 |
这个作业的目标 | 完成个人项目论文查重系统,熟悉psp,测试,性能分析,异常处理等内容。 |
一.github链接:https://github.com/gzjgit-hub/3122004945
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | 470 | 510 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 120 |
· Design Spec | · 生成设计文档 | 20 | 20 |
· Design Review | · 设计复审 | 20 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 180 | 200 |
· Code Review | · 代码复审 | 20 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 50 | 40 |
Reporting | 报告 | 80 | 90 |
· Test Repor | · 测试报告 | 40 | 40 |
· Size Measurement | · 计算工作量 | 10 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
· 合计 | 610 | 660 |
二.需求
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位。
三.计算模块接口的设计与实现过程
代码组织结构
-
Main类:包含
main
方法,是程序的入口点。负责处理命令行参数、读取文件、调用分析函数、计算SimHash值、计算相似度并输出结果。 -
异常类:包括
FileAnalyseException
、HashException
和NotExistFileException
,用于处理特定的错误情况。 -
辅助方法:
readFile
:读取文件内容。writeFile
:将结果写入文件。analyseText
:分析文本,提取关键词和词频。calculateSimHash
:计算SimHash值。wordHash
:对单个词进行哈希处理。
关键函数及其关系
main
:程序入口,调用其他方法。readFile
:读取文件内容,捕获异常。writeFile
:写入结果到文件,捕获异常。analyseText
:分析文本,提取关键词和词频,是SimHash计算的基础。calculateSimHash
:根据词频和哈希值计算SimHash。wordHash
:对词进行哈希,生成固定长度的二进制字符串。
算法关键点
-
文本分析:使用HanLP库进行中文分词和关键词提取,这是文本相似度计算的基础。
-
SimHash算法:
- 对每个关键词进行哈希,生成固定长度的二进制字符串。
- 根据词频调整哈希值,高频词对最终的SimHash值影响更大。
- 将所有关键词的哈希值合并,生成最终的SimHash值。
-
相似度计算:通过比较两个SimHash值的汉明距离来计算文本的相似度。
独到之处
-
异常处理:通过自定义异常类,使得错误处理更加清晰和具体。
-
文本分析的健壮性:通过检查关键词数量和文本内容的空值,增加了程序的健壮性。
-
SimHash值的精确计算:通过精确控制哈希值的长度和格式,确保SimHash算法的准确性。
消除了所有警告:
四.计算模块接口部分的性能改进
性能分析图
五.计算模块部分单元测试展示
测试函数说明
testWriteReadFile:测试文件写入和读取功能是否正常。
testReadFileNotExist:测试尝试读取一个不存在的文件时是否正确处理。
testFileAnalyseException:测试当输入文本为null、空字符串或仅包含空格时,是否抛出FileAnalyseException。
testReadFile:测试读取文件并进行文本分析(分词)的功能。
testWordHash:测试MD5哈希函数是否正确生成128位的哈希值。
testHashException:测试当输入为空字符串或null时,哈希函数是否抛出HashException。
testCalculateSimHash:测试SimHash计算是否正确,并且生成的哈希值长度是否为128位。
testMain:测试主函数main是否能够正确处理命令行参数并执行文件比较。
构造测试数据的思路
testWriteReadFile:
创建一个测试用的文本文件,并写入预期内容。
调用writeFile方法将内容写入文件。
调用readFile方法读取文件内容,并验证是否与预期一致。
testReadFileNotExist:
构造一个不存在的文件路径。
调用readFile方法,并捕获可能抛出的FileNotFoundException。
testFileAnalyseException:
分别传入null、空字符串和仅包含空格的字符串到analyseText方法。
验证是否抛出FileAnalyseException。
testReadFile:
选择一个包含文本的文件路径。
调用readFile方法读取文件内容。
使用读取的内容调用analyseText方法,并打印分词结果。
testWordHash:
使用HanLP.extractKeyword从给定句子中提取关键词。
对每个关键词调用wordHash方法,并打印哈希值。
testHashException:
分别传入空字符串、null和仅包含空格的字符串到wordHash方法。
验证是否抛出HashException。
testCalculateSimHash:
使用给定的句子调用analyseText方法获取词频映射。
调用calculateSimHash方法计算SimHash值,并验证长度是否为128位。
testMain:
构造命令行参数,包括源文件路径、比对文件路径和结果文件路径。
调用main方法,并验证程序是否能够正确执行文件比较。
以下为单元测试得到的测试覆盖率截图。
样例测试:
六.计算模块部分异常处理说明
写入文件测试
读取不存在的文件
文件解析异常
查看分词结果
检测hash值是否为128位
hash异常
计算simhash