一. 作业概述

作业课程 软件工程
作业要求 软件工程作业_2
作业任务 完成一个论文查重系统
GitHub链接 3120006301-duplicate_checking

二.需求分析

题目:论文查重

描述如下:

设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。

原文示例:今天是星期天,天气晴,今天晚上我要去看电影。 抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:

从命令行参数给出:论文原文的文件的绝对路径。 从命令行参数给出:抄袭版论文的文件的绝对路径。 从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。

注意:答案文件中输出的答案为浮点型,精确到小数点后两位

三.PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 20
·Estimate · 估计这个任务需要多少时间 20 20
Development 开发 300 380
· Analysis · 需求分析 (包括学习新技术) 120 180
· Design Spec · 生成设计文档 20 30
· Design Review · 设计复审 10 10
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 10
· Design · 具体设计 60 80
· Coding · 具体编码 60 90
· Code Review · 代码复审 20 15
· Test · 测试(自我测试,修改代码,提交修改) 30 25
Reporting 报告 40 30
· Test Repor · 测试报告 20 18
· Size Measurement · 计算工作量 10 6
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 10 6
All 合计 390 460

四.计算模块接口的设计与实现过程

1.核心算法

知乎_SimHash算法计算相似度

1.1SimHash算法

simHash算法主要有五个过程:分词、Hash、加权、合并、降维。

1.分词

对给定的一段文本进行分词,产生n个特征词,并赋予每个特征词一个权重。比如一段文本为“中国科大计算机系的学生的能力怎么样”,产生的特征词就应该是“中国科大”、“计算机系”、“的”、“学生”、“能力”、“怎么样”,然后对这些词分别赋予权重,假设有1-5五个分类,分词之后以上五个词便会各有一个权重,比如中国科大(4)、计算机系(3)、的(1)、学生(4)、能力(5)、怎么样(3)。

其中,数字越大,代表特征词在句子中的重要性就越高。这样,我们就得到了一个文本的分词的词向量和每个词向量对应的权重。

2.Hash

通过hash函数对每一个词向量进行映射,产生一个n位二进制串,比如CSDN的hash值就是100101。

3.加权

前面的计算我们已经得到了每个词向量的Hash串和该词向量对应的权重,这一步我们计算权重向量W=hash*weight。

具体的计算过程如下:hash二进制串中为1的乘以该特征词的分词权重,二进制串中为0的乘以该特征词的分词权重后取负,继而得到权重向量。

举个例子,CSDN的hash二进制串是100101,CSDN的权重是3,那么生成的权重向量就是[3,-3,-3,3,-3,3]。

4.合并

对于一个文本,我们计算出了文本分词之后每一个特征词的权重向量,在合并这个阶段,我们把文本所有词向量的权重向量相累加,得到一个新的权重向量,形如[3,4,1,5,-5,1]

5.降维

对于前面合并后得到的文本的权重向量,大于0的位置1,小于等于0的位置0,就可以得到该文本的SimHash值,以上面提到的[3,4,1,5,-5,1]为例,我们得到[1,1,1,1,0,1]这个bit串,也就是论文中提及的该文本的指纹。

到此为止,我们已经计算出了一个文本的SimHash值。那么,如何判断两个文本是否相似呢?我们要用到海明距离。

1.2计算海明距离

简单的说,海明距离可以理解为,两个二进制串之间相同位置不同值的个数。举个例子,[1,1,1,0,0,0]和[1,1,1,1,1,1]的海明距离就是3。

在处理大规模数据的时候,我们一般使用64位的SimHash,正好可以被一个long型存储。这种时候,海明距离在3以内就可以认为两个文本是相似的。

2.接口的设计关系

模块 功能
A_main 实现类
ShortStringException 处理文本过短异常
SimHash 计算SimHash值
Hamming 计算海明距离
TXT_IO 文本的IO操作

2.1 A_main

读取命令行参数,将第1个args路径作为原文,第2个args路径作为抄袭文,写入第3个args路径的文本内。

2.2 ShortStringException

public ShortStringException(String message) 当文本长度小于200时异常处理

2.3SimHash

public static String getHash(String str) 获取MD5值 public static String
getSimHash(String str) 传入字符串,通过分词,Hash,加权,合并,最后降维,计算出它的simHash值,并以字符串形式输出

2.4Hamming

public static int getHammingDistance(String simHash1, StringsimHash2) 输入两个simHash值(simHash1、simHash2),计算它们的海明距离 public static
double getSimilarity(String simHash1, String simHash2) 输入两个simHash值,输出相似度

2.5 TXT_IO

public static String readTxt(String txtPath) 读取文本内容,以字符串输出 public
static void writeTxt(double txtElem,String txtPath) 写入文本

3.程序流程图

五.单元测试

1.TXT_IO_text

1.1代码

package se.test;import org.junit.Test;
import se.main.TXT_IO;import static se.main.TXT_IO.*;public class TXT_IO_test {@Testpublic void readTxtTest() {// 路径存在,正常读取String str = readTxt("txt/orig.txt");String[] strings = str.split(" ");for (String string : strings) {System.out.println(string);}}@Testpublic void writeTxtTest() {// 路径存在,正常写入double[] elem = {0.1, 0.2, 0.3, 0.4, 0.5};for (int i = 0; i < elem.length; i++) {writeTxt(elem[i], "txt/ans.txt");}}@Testpublic void readTxtFailTest() {// 路径不存在,读取失败String str = readTxt("txt/none.txt");}@Testpublic void writeTxtFailTest() {// 路径错误,写入失败double[] elem = {0.1, 0.2, 0.3, 0.4, 0.5};for (int i = 0; i < elem.length; i++) {writeTxt(elem[i], "User:/test/ans.txt");}}}

1.2测试结果


2.ShortStringException_text

2.1代码

package se.test;import org.junit.Test;
import se.main.SimHash;public class ShortStringException_test {@Testpublic void shortStringExceptionTest(){//测试str.length()<200的情况System.out.println(SimHash.getSimHash("孤独之旅"));}}

2.2测试结果

3.SimHash_text

3.1代码

package se.test;import org.junit.Test;
import se.main.SimHash;
import se.main.TXT_IO;public class SimHash_test {@Testpublic void getHashTest(){String[] strings = {"我", "在", "GDUT", "2021级计算机科学与技术", "学习", "软件工程"};for (String string : strings) {String stringHash = SimHash.getHash(string);System.out.println(stringHash.length());System.out.println(stringHash);}}@Testpublic void getSimHashTest(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_add.txt");System.out.println(SimHash.getSimHash(str0));System.out.println(SimHash.getSimHash(str1));}}

3.2测试结果

4.Hamming_text

4.1代码

package se.test;import org.junit.Test;
import se.main.Hamming;
import se.main.SimHash;
import se.main.TXT_IO;public class Hamming_test{@Testpublic void getHammingDistanceTest() {String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_add.txt");int distance = Hamming.getHammingDistance(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("海明距离:" + distance);System.out.println("相似度: " + (100 - distance * 100 / 128) + "%");}@Testpublic void getHammingDistanceFailTest() {// 测试str0.length()!=str1.length()的情况String str0 = "1010";String str1 = "1111";System.out.println(Hamming.getHammingDistance(str0, str1));}@Testpublic void getSimilarityTest() {String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_add.txt");int distance = Hamming.getHammingDistance(SimHash.getSimHash(str0), SimHash.getSimHash(str1));double similarity = Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("str0和str1的汉明距离: " + distance);System.out.println("str0和str1的相似度:" + similarity);}
}

4.2测试结果

5.A_main_text

此部分对作业所给的6个测试文本进行测试,其中原文为orig.txt,抄袭文本为所有txt文本。

5.1代码

package se.test;import org.testng.annotations.Test;
import se.main.Hamming;
import se.main.SimHash;
import se.main.TXT_IO;public class A_main_test
{@Testpublic void origAndOrigTest(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig.txt");String ansFileName = "txt/ansAndOrigTest.txt";double ans = Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("查重率:"+ans*100+"%");TXT_IO.writeTxt(ans, ansFileName);}@Testpublic void origAndAddTest(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_add.txt");String ansFileName = "txt/ansAndAddTest.txt";double ans =Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("查重率:"+ans*100+"%");TXT_IO.writeTxt(ans, ansFileName);}@Testpublic void origAndDelTest(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_del.txt");String ansFileName = "txt/ansAndDelTest.txt";double ans = Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("查重率:"+ans*100+"%");TXT_IO.writeTxt(ans, ansFileName);}@Testpublic void origAndDis1Test(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_dis_1.txt");String ansFileName = "txt/ansAndDis1Test.txt";double ans = Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("查重率:"+ans*100+"%");TXT_IO.writeTxt(ans, ansFileName);}@Testpublic void origAndDis10Test(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_dis_10.txt");String ansFileName = "txt/ansAndDis10Test.txt";double ans = Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("查重率:"+ans*100+"%");TXT_IO.writeTxt(ans, ansFileName);}@Testpublic void origAndDis15Test(){String str0 = TXT_IO.readTxt("txt/orig.txt");String str1 = TXT_IO.readTxt("txt/orig_0.8_dis_15.txt");String ansFileName = "txt/ansAndDis15Test.txt";double ans = Hamming.getSimilarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));System.out.println("查重率:"+ans*100+"%");TXT_IO.writeTxt(ans,ansFileName);}}

5.2测试结果

六.测试结果

在终端使用jar包给出命令行参数,得到查重(Duplicate Checking Rate)结果如下

七.程序缺陷

适用于较长文本的去重场景,对短文本不太合适,容易冲突生成相同simhash值,存在误判情况。

Java实现文本查重相关推荐

  1. [转]simhash进行文本查重

    有1亿个不重复的64位的01字符串,任意给出一个64位的01字符串f,如何快速从中找出与f汉明距离小于3的字符串? 大规模网页的近似查重 主要翻译自WWW07的 Detecting Near-Dupl ...

  2. Java实现文件查重去重

    Java实现文件查重去重 前言 大概流程 代码 前言 网上下的一些去重软件不是太慢就是去的不够干净,故用Java编写一个使用 大概流程 ① 遍历选定的文件并按照文件长度分组 ② 根据md5二次过滤分组 ...

  3. 文本查重:知识点总结

    目录 整体框架 1. 查询文本切分策略 2. 文本相似性计算 2.1 计算粒度 2.2 相似性度量算法 2.3 整体相似度的评估 文本相似度 simhash算法及原理简介 1. 什么是SimHash ...

  4. [附源码]计算机毕业设计JAVA文章管理系统查重PPT

    [附源码]计算机毕业设计JAVA文章管理系统查重PPT 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(I ...

  5. 大量文本查重相似度计算功能设计-基于simhash+相似度算法

    最近做文本查重功能,陆续遇到一些问题,做一下记录: 1.simhash分桶策略,只适合基本完全相同的文本查重,比如网页查重.64位simhash如果有3位以内的海明距离,则认为文本一致:存储使用hba ...

  6. 【代码模板】simHash算法文本查重(golang代码实现)

    ps: 供自己以后参考以及供了解simhash算法的人看 本代码针对通用文本查重,故所有分词的权重均为1 由于没有安装分词器,所以目前只能对英文句子进行相似度检测 代码只提供一个大致思路,没有做进一步 ...

  7. 【JavaWeb 爬虫】Java文本查重网页版 爬取百度搜索结果页全部链接内容

    ! ! 更新:增加了网页过滤判断,只允许域名包含blog,jianshu的网站通过 小技巧 Java中InputStream和String之间的转换方法 String result = new Buf ...

  8. Java实现登录查重实例

    实现Javaweb中 用户登录登录是一个十分重要的部分 今天用Java中的异常方法来模拟查重过程 分析: 现实生活中,我们在登录注册的时候,访问数据库,很多应用不允许ID或者用户名重复,在注册操作时, ...

  9. Java实现论文查重系统

    1.论文查重系统背景 日常生活中投票是非常常见的一件事,随着现在科技的发展,电子投票都是以线上操作的形势完成,本系统为模仿电子投票系统所作. a.本系统有管理员登录,个人信息修改,用户管理,投票管理, ...

  10. java中sql查重跟去重_sql中查重和去重

    在这记录一个实习期间遇到的一个查重和去重的sql语句. 查重语句:(group by 查重) SELECT user_id, count(*) as num FROM 表名 WHERE 条件  GRO ...

最新文章

  1. node 判断文件夹是否存在
  2. Silverlight Blend动画设计系列四:倾斜动画(SkewTransform)
  3. redhat安装wine教程_Ubuntu怎么下载应用并安装应用
  4. mac你没有权限打开应用程序_如何管理Mac的隐私权限控制
  5. 魅族15无法连接计算机,还在为数据丢失而烦恼?魅族15告诉你什么叫做碎屏无忧...
  6. NeurIPS 2021 | 视频压缩框架DCVC:从残差编码到条件编码,建模上下文
  7. c语言如何引用参数,关于exec:如何在C语言中使用适当的参数调用execl()?
  8. 05-01 docker 介绍
  9. C和指针---读书笔记16
  10. 语言模拟蒲丰问题_播音主持专业艺考模拟主持八大禁忌!
  11. MySQL复制之gtid_purged与gtid_executed
  12. 计算机毕业设计之java+springboot基于vue的地方废物回收机构管理系统
  13. 手把手带你入门 API 开发
  14. 三层交换机光模块故障排除流程
  15. win10系统瑞星杀毒的卸载
  16. windows设置CPU主频
  17. MyBatis07:使用注解开发
  18. C/C++编程:Google代码规范
  19. 基于射频RFID智能刷卡门禁系统设计(毕设课设)
  20. 对象在内存中是如何存储的(内存五大区域和类加载)

热门文章

  1. 服务出现TCP连接快速增加尤其是NON_ESTABLISHED大量增加导致内存和CPU暴增系统无法使用的问题
  2. 2276计算机基础与程序设计,浙大建筑
  3. PPT设置自动保存时间 mac_MAC上如何把PDF转换成PPT
  4. CAN通信采样点(Sample Point Position)及采样点测试
  5. 悠然乱弹:借船下海还是造船下海
  6. QT 写一个属于自己的消息弹窗MessageBox
  7. anaconda中下载urllib2的问题,以及所有的调试均在python3.x版本
  8. Mybatis 报错:ORA-00947: 没有足够的值
  9. Vue.js中Ueditor如何引用 youtube视频源发布(已解决)
  10. SpringBoot+vue部署服务器(后台运行)