第一次个人编程作业
第一次编程作业
| 软件工程 | 19级信安12班 |
|---|---|
| 作业要求 | 个人项目作业 |
| 作业目标 | 论文查重、代码测试、PSP表格、性能分析、GitHub上传、博客总结 |
1.作业Github地址
https://github.com/zhouhuajuan/3219005498.git
2.需求
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
3.核心算法
本项目使用的核心算法是SimHash算法+海明距离。
1.算法简介
SimHash也即相似hash,是一类特殊的信息指纹,常用来比较文章的相似度,与传统hash相比,传统hash只负责将原始内容尽量随机的映射为一个特征值,并保证相同的内容一定具有相同的特征值。而且如果两个hash值是相等的,则说明原始数据在一定概率下也是相等的。但通过传统hash来判断文章的内容是否相似是非常困难的,原因在于传统hash只唯一标明了其特殊性,并不能作为相似度比较的依据。
2.算法原理

3.算法实现流程
1.SimHash
(1)分词:对文本进行分词,得到 N 个 词 word1word_1word1,word2word_2word2,word3word_3word3 …… wordnword_nwordn;
(2)赋权重:对文本进行词频统计,为各个词设置合理的权重 weight1weight_1weight1,weight2weight_2weight2,weight3weight_3weight3 …… weightnweight_nweightn;
(3)哈希:计算每个分词的哈希值 hashihash_ihashi,得到一个定长的二进制序列,一般是 64 位,也可以是 128 位;
(4)加权重:变换每个分词 wordiword_iwordi 的 hashihash_ihashi,将 1 变成正的权重值 weightiweight_iweighti,0 变成 −weighti-weight_i−weighti,得到一个新的序列 weightHashiweightHash_iweightHashi;
(5)叠加权重:对每个 weightHashiweightHash_iweightHashi 各个位上的数值做累加,最终得到一个序列 lastHashlastHashlastHash,序列的每一位都是所有分词的权重的累加值;
(6)降维:再将 lastHashlastHashlastHash 变换成 01 序列 simHash ,方法是:权重值大于零的位置设置为 1,小于 0 的位置设置为 0,它就是整个文本的局部哈希值,即指纹。
算法实现需要解决的三个技术点:
分词,有 hanlp 分词、IKAnalyzer 分词 和 word 分词等工具可以用;
权重,为各个分词赋上合理的权重,可以自定义统计算法,也可以借助 word 的词频统计;
哈希算法,这个可以自己选择,也可以用现有的算法,如 Murmur 哈希,JDK 的 hash 。
流程图为:

2.海明距离
汉明距离是以理查德·卫斯里·汉明的名字命名的。在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。从其定义上来看,就是二进制序列异或计算时相异为1,异或的结果中1的总数,就是两个字符串的汉明距离,所以实现汉明距离计算的方法也很简单。
3.接口的设计和实现
0.项目结构

1.FileUtil:文件的读写工具类

(1)readFile():读文件方法,根据传入的文件路径,读取文本内容并转为字符串返回
(2)writeFile():写文件方法,两个参数分别为double型的相似度和要写入的文件路径,如果这个文件存在直接写入,如果不存在将在对应位置创建一个新文件再写入
2.SimHashUtil:获取SimHash码的工具类

(1)getHash():传入字符串,使用MD5获取hash值
(2)getSimHash():参数为读取文件得到的字符串,利用HanLp分词并同时赋权,调用getHash()方法得到每个关键字的hash值,加权后降维,返回的是得到的SimHash码
3.HammingDistanceUtil:计算海明距离的工具类

(1)getDistance():参数为两个文本的SimHash值,判断两个SimHash是否长度一致,如果不一致是无法计算海明距离的。若一致,对每一位进行异或运算,统计异或运算后1的数量distance,最后返回的就是这个int型的distance
(2)getSimilarity():参数为两个文本的SimHash值,调用getDistance()方法得到distance,通过公式0.01 * (100 - distance * 100 / 128)得到的结果就是两个文本的相似度
4.Solution:主类

5.Exception异常类
0.总览

在本次论文查重项目中,一共定义了5个处理异常类。下面详细讲解每个异常类。
1.文本内容为空异常

读取文件时若文本内容为空,自然是无法与原文件进行比对,得到相似度。故调用FileUtil类的readFile()方法时,如果得到的字符串str.size()==0,则抛出FileIsNullException异常。
2.文本内容过短异常

读取路径得到的文本内容如果过小,在分词的时候可能取不到关键字,故取不到它的哈希码。因此调用FileUtil类的readFile()方法时,如果得到的字符串15<str.size()<150,则抛出FileIsShortException异常。
3.文件路径错误异常

文件路径错误有两种情况,包括错误的路径和不存在的路径,比如当读取一个不存在的路径(E:\rg\null.txt)或者一个错误的路径(F:\rg\null.txt)时,我的电脑里只有E盘,没有F盘,E盘没有null.txt文件,故在调用FileUtil类的readFile()方法时,会因为找不到指定路径的文件而报错;除此之外,写入一个错误路径的文件(F:\rg\null.txt)也是会报错的。
4.文本长度小于15引起的分权错误

在计算SimHash码时,由于本人定义getSimHash()方法的局限性,当文本的长度小于15,会使得分权运算中除数为0,因此需要保证文本的长度>15。
5.两个文本的SimHash长度不等

得到两个文本的SimHash码后,如果SimHash的长度不等就不能计算海明距离,捕获异常。
4.接口的性能改进
1.内存占用情况

2.类的占用情况


3.CPU负载

5.单元测试展示
1.SolutionTest
-
代码
![]()
-
测试结果
![]()
2.FileUtilTest
-
代码
![]()
-
测试结果
![]()
-
测试覆盖率
![]()
3.SimHashUtilTest
-
代码
![]()
-
测试结果
![]()
-
测试覆盖率
![]()
4.HammingDistanceTest
-
代码
![]()
-
测试结果
![]()
-
测试覆盖率
![]()
5.ExceptionTest
-
代码
![]()
-
测试结果
![]()
-
测试覆盖率
![]()
6.可运行程序测试


6.异常处理说明
1.文本内容为空异常

读取文件后得到的文本str如果长度为0,说明文本内容为空,捕获FileIsNullException异常。
2.文本内容过短异常

如果读取文件后得到的文本小于150字,文本内容过短取不到关键字,捕获FileIsShortException异常。
3.文件路径错误异常

将结果写入一个错误的文件,系统找不到指定路径,捕获FileIsWrongException异常。
4.两个文本的SimHash长度不等

如果SimHash长度不一致,无法计算海明距离,捕获SimHashException异常。
5.文本长度小于15引起的分权错误

由于定义分权合并的局限性,文本长度必须大于15,否则会使关键字分权为0,这不是我们想得到的。捕获WeightIsWrongException异常。
7.PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 45 | 60 |
| Estimate | 估计这个任务需要多少时间 | 80 | 97 |
| Development | 开发 | 45 | 67 |
| Analysis | 需求分析(包括学习新技术) | 5 | 5 |
| Design Spec | 生成设计文档 | 2 | 2 |
| Design Review | 设计复审 | 15 | 20 |
| Coding Standard | 代码规范(为目前的开发制定合适的规范) | 10 | 10 |
| Design | 具体设计 | 5 | 4 |
| Coding | 具体编码 | 40 | 60 |
| Code Review | 代码复审 | 30 | 76 |
| Test | 测试(自我测试,修改代码,提交修改) | 28 | 44 |
| Reporting | 报告 | 30 | 65 |
| Test Repor | 测试报告 | 25 | 40 |
| Size Measurement | 计算工作量 | 10 | 15 |
| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 20 | 21 |
| 合计 | 390 | 586 |















浙公网安备 33010602011771号