203
社区成员




这个作业属于哪一个课程 | 软件工程 |
---|---|
第一次个人编程作业 | 班级链接 |
作业要求 | 作业要求,论文查重 |
这个作业的目标 | 完成个人编程作业编码部分,并进行测试和博客创作 |
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
PSP2.1 | Personal Software process Stages 预估耗时(min) 实际耗时(min) | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
·Estimate | 估计这个任务需要多长时间 | 200 | 520 |
Development | 开发 | ||
·Analysis | ·需求分析(包括学习新技术) | 90 | 100 |
·Design Spec | ·生成设计文档 | 30 | 40 |
·Design Review | ·设计复审 | 25 | 30 |
·Coding Standard | ·代码规范 | 15 | 20 |
·Design | ·具体设计 | 80 | 40 |
·Code Review | ·代码复审 | 40 | 50 |
·Test | ·(自我测试,修改代码,提交修改) 测试 | 60 | 90 |
Reporting | ·报告 | ||
·Test Repor | ·测试报告 | 40 | 80 |
·Size Measurement | ·计算工作量 | 40 | 40 |
·Postmortem&Process Improvment Plan | ·事后总结,并提出过程改进计划 | 30 | 30 |
Total | ·合计 | 450 | 520 |
设计思路:simhash算法
simhash算法分为5个步骤:分词、hash、加权、合并、降维
具体过程如下所述:
分词
给定一段语句,进行分词,得到有效的特征向量,然后为每一个特征向量设置1-5等5个级别的权重(如果是给定一个文本,那么特征向量可以是文本中的词,其权重可以是这个词出现的次数)。例如给定一段语句:“CSDN博客结构之法算法之道的作者July”,分词后为:“CSDN 博客 结构 之 法 算法 之 道 的 作者 July”,然后为每个特征向量赋予权值:CSDN(4) 博客(5) 结构(3) 之(1) 法(2) 算法(3) 之(1) 道(2) 的(1) 作者(5) July(5),其中括号里的数字代表这个单词在整条语句中的重要程度,数字越大代表越重要。
hash
通过hash函数计算各个特征向量的hash值,hash值为二进制数01组成的n-bit签名。比如“CSDN”的hash值Hash(CSDN)为100101,“博客”的hash值Hash(博客)为“101011”。就这样,字符串就变成了一系列数字。
加权
在hash值的基础上,给所有特征向量进行加权,即W = Hash * weight,且遇到1则hash值和权值正相乘,遇到0则hash值和权值负相乘。例如给“CSDN”的hash值“100101”加权得到:W(CSDN) = 100101 4 = 4 -4 -4 4 -4 4,给“博客”的hash值“101011”加权得到:W(博客)=101011 5 = 5 -5 5 -5 5 5,其余特征向量类似此般操作。
合并
将上述各个特征向量的加权结果累加,变成只有一个序列串。拿前两个特征向量举例,例如“CSDN”的“4 -4 -4 4 -4 4”和“博客”的“5 -5 5 -5 5 5”进行累加,得到“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”,得到“9 -9 1 -1 1”。
降维
对于n-bit签名的累加结果,如果大于0则置1,否则置0,从而得到该语句的simhash值,最后我们便可以根据不同语句simhash的海明距离来判断它们的相似度。例如把上面计算出来的“9 -9 1 -1 1 9”降维(某位大于0记为1,小于0记为0),得到的01串为:“1 0 1 0 1 1”,从而形成它们的simhash签名。
本文采用余弦相似度
解释见使用余弦相似度计算文本相似度
相似度计算模块
int sum1 = 0;
int sum2 = 0;
int sAB = 0;
for (int i=0;i<words1.size();i++){
int a = FA.get(i);
int b = FB.get(i);
sAB += ab;
sum1 += aa;
sum2 += b*b;
}
double A = Math.sqrt(sum1);
double B = Math.sqrt(sum2);
BigDecimal AB = BigDecimal.valueOf(A).multiply(BigDecimal.valueOf(B));
return BigDecimal.valueOf(sAB).divide(AB, 3, BigDecimal.ROUND_HALF_UP).doubleValue();
}
心得
对于暂缓返校的我来说本次作业好难,线上上课都听的很费劲更不用说是怎么做作业。我觉得本次作业做的不好自己也不太满意,但还是尽力了,还有GitHub操作,以我这个水平很有难度,回校后想跟老师和同学们问自己不会的把后面作业做的要好点。