文章目录

  • 0 作业基本信息
  • 1 作业地址:[https://gitcode.net/willwill0915/papercheck](https://gitcode.net/willwill0915/papercheck)
  • 2 PSP表格
  • 3 模块接口的设计与实现过程
    • 3.1 共5个类8个方法
    • 3.2 类,方法之间的关系
    • 3.3 关键函数getSimHash流程图
  • 4 模块接口部分的性能改进
  • 5 单元测试展示
    • 5.1 TxtIOUtilsTest测试展示
    • 5.2 SimHashUtilsTest测试展示
    • 5.3 HammingUtilsTest测试展示
    • 5.4 MainPaperCheckTest测试展示
  • 6 异常处理说明
    • 6.1 TooShortException
    • 6.2 NotTxtException

0 作业基本信息

作业所属课程 软件工程3班
作业要求 个人项目作业-论文查重
作业目标 1. 熟练使用git;
2. 学习PSP表格;
3. 编写论文查重算法;
4. 使用性能分析工具分析代码性能;
5. 使用单元测试进行测试。
代码仓库 https://gitcode.net/willwill0915/papercheck

1 作业地址:https://gitcode.net/willwill0915/papercheck

PS:源代码编译打包后的程序为如图:

仓库中releases的 main.jar 为编译打包后的main-jar-with-dependencies.jar,为符合作业要求更改此jar包名称为main.jar
若您需要clone代码进行重新编译,请使用main-jar-with-dependencies.jar
示例:java -jar main-jar-with-dependencies.jar E:\zzz\orig.txt E:\zzz\orig_0.8_add.txt E:\zzz\ansAll.txt

2 PSP表格

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

3 模块接口的设计与实现过程

3.1 共5个类8个方法

方法
MainPaperCheck(查重主程序类) main方法
MyException(异常处理类) cast(异常抛出方法)
HammingUtils(海明距离模块工具类) getHammingDistance(计算海明距离)
getSimilarity(输出相似度)
SimHashUtils(SimHash模块工具类) getHash(计算哈希值)
getSimHash(计算simHash值)
TxtIOUtils(txt文件读写工具类) readTxt(读取txt文本内容)
writeTxt(向txt文件输出文本)

3.2 类,方法之间的关系

  1. 主程序调用文件读写工具对文本路径中的文件进行读取;
  2. 对读取的文件类型进行判断,非txt文件将抛出异常;
  3. 对文件文本内容进行字数判断,少于300字抛出异常;
  4. 使用SimHash模块工具类分别对两个文本获取simHash值;
  5. 使用海明距离模块工具类计算两个文本的海明距离,在根据海明距离计算相似度;
  6. 对结果进行小数点后保留两位处理;
  7. 结果输出。

3.3 关键函数getSimHash流程图

[分词] ——> [获取hash值] ——> [加权] ——> [合并] ——> [降维获取simHash]

4 模块接口部分的性能改进

  • 性能分析图(由JProfiler11生成)Overview

方法调用情况

  • 程序消耗最大的函数
    /*** @param str 传入字符串* @return java.lang.String  返回str的simHash值* @description 传入String, 计算出它的simHash值,并以字符串形式输出* @author will* @date 2023/3/4 15:16*/public static String getSimHash(String str) {//文本长度太短时HanLp无法取得关键字try {if (str.length() < 300) {MyException.cast("文本字符长度不能少于300字");}} catch (MyException myException) {myException.printStackTrace();return null;}//用数组表示特征向量,取128位,从 0 1 2 位开始表示从高位到低位int[] v = new int[128];//1. 分词(使用了外部依赖hankcs包提供的接口)//取出所有关键词List<String> keywordList = HanLP.extractKeyword(str, str.length());//hashint size = keywordList.size();//以i做外层循环int i = 0;for (String keyword : keywordList) {//2. 获取hash值String keywordHash = getHash(keyword);if (keywordHash.length() < 128) {//hash值可能少于128位,在低位以0补齐int dif = 128 - keywordHash.length();for (int j = 0; j < dif; j++) {keywordHash += "0";}}//3. 加权、合并for (int j = 0; j < v.length; j++) {// 对keywordHash的每一位与'1'进行比较if (keywordHash.charAt(j) == '1') {//权重分10级,由词频从高到低,取权重10~0v[j] += (10 - (i / (size / 10)));} else {v[j] -= (10 - (i / (size / 10)));}}i++;}//4. 降维//储存返回的simHash值String simHash = "";for (int j = 0; j < v.length; j++) {// 从高位遍历到低位if (v[j] <= 0) {simHash += "0";} else {simHash += "1";}}return simHash;}

5 单元测试展示

5.1 TxtIOUtilsTest测试展示

  • 代码展示
package com.will.utils;import org.junit.Test;/*** @author will* @version 1.0* @description txt文件读写工具类测试* @date 2023/3/4 14:58*/
public class TxtIOUtilsTest {//文件类型不是txt类型@Testpublic void readNotTxtTest(){String str = TxtIOUtils.readTxt("E:\\zzz\\test.java");System.out.println(str);}//路径存在,正常读取@Testpublic void readTxtTest() {String str = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig.txt");System.out.println(str);/*String[] strings = str.split(" ");for (String string : strings) {System.out.println(string);}*/}//路径存在,正常写入@Testpublic void writeTxtTest() {TxtIOUtils.writeTxt("你好,今天是星期日,我不想学习,但是作业太多了,好烦","E:\\zzz\\writehere.txt");}//路径不存在,读取失败@Testpublic void readTxtFailTest() {String str = TxtIOUtils.readTxt("D:/test/none.txt");}//路径错误,写入失败@Testpublic void writeTxtFailTest() {TxtIOUtils.writeTxt("你好,今天是星期日,我不想学习,但是作业太多了,好烦","D:/test/none.txt");}
}
  • 测试思路

    • txt文本类型文件的IO主要考虑的是:
    1. 读取的文件是否符合txt文本类型;
    2. 路径存在与否是否读取正常;
    3. 文本是否支持中文读取,是否会乱码。
  • 测试覆盖率截图

5.2 SimHashUtilsTest测试展示

  • 代码展示
package com.will.utils;import org.junit.Test;/*** @author will* @version 1.0* @description SimHash模块工具类测试类* @date 2023/3/4 15:18*/
public class SimHashUtilsTest {//获取字符串Hash测试@Testpublic void getHashTest() {String[] strings = {"余华", "是", "一位", "真正", "的", "作家"};for (String string : strings) {String stringHash = SimHashUtils.getHash(string);System.out.println(stringHash.length());System.out.println(stringHash);System.out.println("=====================");}}//获取字符串SimHash测试@Testpublic void getSimHashTest() {String orig = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig.txt");String orig_add = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_add.txt");System.out.println(orig + ": \n" + SimHashUtils.getSimHash(orig));System.out.println("=====================");System.out.println(orig_add + ": \n" + SimHashUtils.getSimHash(orig_add));System.out.println("=====================");}
}
  • 测试思路:给定字符串获取其hash和Simhash值
  • 测试覆盖率截图

5.3 HammingUtilsTest测试展示

  • 代码展示
package com.will.utils;import org.junit.Test;/*** @author will* @version 1.0* @description 海明距离模块工具类测试* @date 2023/3/4 15:35*/
public class HammingUtilsTest {//获取海明距离@Testpublic void getHammingDistanceTest() {String str0 = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig.txt");String str1 = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_add.txt");int distance = HammingUtils.getHammingDistance(SimHashUtils.getSimHash(str0), SimHashUtils.getSimHash(str1));System.out.println("海明距离:" + distance);System.out.println("相似度: " + (100 - distance * 100 / 128) + "%");}//获取海明距离失败测试@Testpublic void getHammingDistanceFailTest() {// 测试str0.length()!=str1.length()的情况String str0 = "10101010";String str1 = "1010101";System.out.println(HammingUtils.getHammingDistance(str0, str1));}//获取相似度测试@Testpublic void getSimilarityTest() {String str0 = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig.txt");String str1 = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_add.txt");int distance = HammingUtils.getHammingDistance(SimHashUtils.getSimHash(str0), SimHashUtils.getSimHash(str1));double similarity = HammingUtils.getSimilarity(SimHashUtils.getSimHash(str0), SimHashUtils.getSimHash(str1));System.out.println("str0和str1的汉明距离: " + distance);System.out.println("str0和str1的相似度:" + similarity);}
}
  • 测试思路:计算海明距离失败条件的测试,给定两个文本计算海明距离,根据海明距离获取相似度。
  • 测试覆盖率截图

5.4 MainPaperCheckTest测试展示

  • 代码展示
package com.will.runmain;import com.will.utils.HammingUtils;
import com.will.utils.SimHashUtils;
import com.will.utils.TxtIOUtils;
import org.junit.Test;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** @author will* @version 1.0* @description 测试主程序类* @date 2023/3/4 15:53*/
public class MainPaperCheckTest {//测试原文件与所有测试文件的相似度@Testpublic void origAndAllTest() {String[] str = new String[6];str[0] = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig.txt");str[1] = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_add.txt");str[2] = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_del.txt");str[3] = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_dis_1.txt");str[4] = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_dis_10.txt");str[5] = TxtIOUtils.readTxt("C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\orig_0.8_dis_15.txt");String ansFileName = "C:\\Users\\76757\\OneDrive\\桌面\\java论文查重的测试txt文件\\ansAll.txt";for (int i = 0; i <= 5; i++) {Double similarity = HammingUtils.getSimilarity(SimHashUtils.getSimHash(str[0]), SimHashUtils.getSimHash(str[i]));//保留小数点后两位String resultSimilarity = String.format("%.2f", similarity);String result = "查重时间:" + DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss").format(LocalDateTime.now()) + "===" + "原文件与文件" + i + "的相似度为:" + resultSimilarity + "\r\n";TxtIOUtils.writeTxt(result, ansFileName);System.out.println(result);}}}
  • 测试思路:使用循环遍历,将样本原文本与测试样本分别计算其相似度。
  • 测试覆盖率截图

6 异常处理说明

6.1 TooShortException

  • 设计目标:为防止文本长度太短时HanLp无法取得关键字而设立的规范文本长度过短异常。
  • 对应场景:当读取的文本内容少于300字符时将抛出。
  • 测试样例:
package com.will.exception;import com.will.utils.SimHashUtils;
import org.junit.Test;/*** @author will* @version 1.0* @description TODO* @date 2023/3/4 23:13*/
public class TooShortExceptionTest {@Testpublic void shortStringExceptionTest() {//测试str.length()<300的情况System.out.println(SimHashUtils.getSimHash("哈哈哈哈哈哈哈哈"));}@Testpublic void longStringExceptionTest() {//测试str.length()>300的情况String str = "哈哈就扫地机怕是广东工业大学是本科还是大专????????????鸡扒" +"结果阿斯顿股票v好的抛光回家sad感觉哦怕个soadfjpgjogsdjf;alskjf撒个娇安排宫颈癌" +"我想脱单这里有人能看到吗???打牌哦福建省就是怕的皮广东工业大学是本科还是大专派收到饭东坡" +"这里可以随意发疯吗????哦动第三大街佛收到反暗室逢灯扒山阿返东发的发票安师傅按时" +"飞盘的积分披萨福建省AD广东工业大学是本科还是大专sa9pugpadsufseuf980weuwe9rfuweghisduf" +"hfjoiasdufo广东工业大学是本科还是大专广东工业大学是本科还是大专uwe90urweioupasusadof" +"ujdaospfupsovhasfpjsafsd" +"ujifusoffjweprjfwefwf";System.out.println(SimHashUtils.getSimHash(str));System.out.println(str.length());}}
  • 测试结果

6.2 NotTxtException

  • 设计目标:txtIO读取文件避免读取非txt文本类型的文件。

  • 对应场景:当读取的文本文件为非txt文件时将抛出。

  • 测试样例

package com.will.exception;import com.will.utils.TxtIOUtils;
import org.junit.Test;/*** @author will* @version 1.0* @description TODO* @date 2023/3/5 11:07*/
public class NotTxtExceptionTest {@Testpublic void NotTxtExceptionTest() {String str = TxtIOUtils.readTxt("E:\\zzz\\test.java");System.out.println(str);}@Testpublic void IsTxtExceptionTest() {String str = TxtIOUtils.readTxt("E:\\zzz\\test.txt");System.out.println(str);}
}
  • 测试结果

第一次个人编程作业——论文查重相关推荐

  1. 个人项目作业-论文查重

    目录 1.作业基本信息 2.PSP表格 3.计算模块接口的设计与实现过程 3.1类和方法 3.2类.方法之间的调用关系 3.3 关键方法computeTxtSimilar() 4.计算模块接口部分的性 ...

  2. 软件工程个人项目作业----论文查重

    这个作业属于哪个课程 广工2023软件工程课程社区-CSDN社区云 这个作业要求在哪里 个人项目作业-论文查重 这个作业的目标 实现论文查重 其他参考文献 csdn 目录 1.gitcode地址 2. ...

  3. 软件工程第二次作业----论文查重

    1.作业地址 Charles_valuntin / 3121005173 · GitCode 2.PSP表格 PSP2.1 Personal Software Process Stages 预估耗时( ...

  4. 软工个人项目作业——论文查重系统

    文章目录 作业信息 个人仓库 1.计算模块接口的设计与实现过程 类 函数调用流程 核心算法:simhash+海明距离 2.接口设计与实现 读写txt文件的模块 SimHash模块 海明距离模块 mai ...

  5. 软件工程第一次个人编程作业

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 个人项目作业-论文查重 这个作业的目标 个人编程实现论文查重算法并进行测试检验 目录 一.项目链接 二.PSP表格 三.分包.接口设计与实现 四.性 ...

  6. 个人项目-论文查重/3120005470

    文章目录 1.作业的基本信息 2.作业地址 3.PSP表格 4.算法的设计与实现过程 4.1 分词 4.2 hash 4.3 加权 4.4 合并 4.5 降维 4.6 通过海明距离计算simhash的 ...

  7. 大学计算机作业查重,大学生课程作业进行查重?别把“水论文”之过都抛给学生!...

    让一个本科生写出高水平,不重复的论文,不现实,"水论文"这一现象不能全怪学生!(水论文即由学生或由他人代学生撰写的质量水平较低的论文.) 日前,教育部印发<关于狠抓新时代全国 ...

  8. 论文查重是怎么查的?有什么规定?

    论文的参考也是论文写作的一部分,也是我们应该关注的部分.该参考文献若是书写不规范对于查重率也会影响到重复率.那么论文查重是怎么查的,我们在书写时应该注意什么?查重有什么规定呢? 论文查重是怎么查的? ...

  9. 论文查重的步骤是什么?

    论文的查重是一个必要的链接来完成整个论文的写作,但第一次接触论文,应该有很多事情缺乏理解,不知道如何处理,论文查重的步骤是什么?下一步是介绍相关的内容. 论文查重的步骤有哪些 1.首先要做的工作就是可 ...

最新文章

  1. 大数据学习——spark安装
  2. 辽师大计算机科学与技术专业怎么样,性价比很高的大学,辽师大的优势专业分析!家长请收藏...
  3. 机器学习100天:专栏目录
  4. MotionLayout 基础教程
  5. 基于BERT的多模学习——VL-BERT篇
  6. linux 分隔大文件,linux系统下分割大文件的方法
  7. Beyond Compare 4常用配置
  8. C# 异步TCP Socket聊天室(1服务器,N客户端)
  9. 如何用阿里云服务器建立个人网站
  10. Mac 环境endnote 各种问题解决方法和word各种技巧汇总
  11. div和span标签以及标签分类
  12. 物理建模钢琴-Arturia Piano V2 v2.5.0.3410 MacOSX
  13. Q50:TCP如何保证可靠性?
  14. VirtualBox中win7系统无法安装增强功能
  15. 小米平板4刷入twrp
  16. 少年自学python笔记_自学python笔记(一)
  17. Cadence Virtuoso IC617从原理图建立器件和生成版图
  18. NDK开发之ndk-build命令详解
  19. 怒了!维基解密开放爆料数据库,内容涉及全是美国“脏事”!
  20. 基于WSL2+NVIDIA Docker的开发环境最佳实践

热门文章

  1. Android在线生成证书并打包成apk文件
  2. CAD功能工具全自学教程与经典实例
  3. 掌握SEO关键词布局技巧:让您的网站在搜索引擎中翻云覆雨,提升排名和流量
  4. 2021年陕西省安全员C证报名考试及陕西省安全员C证找解析
  5. 注会会计-会计科目组成
  6. DLNA数字家庭网络联盟
  7. java毕业设计-物流管理系统-源码+lw文档+mybatis+系统+mysql数据库+调试
  8. css文字超长显示...
  9. docker向harbor中推送镜像
  10. python+tkinter+nuitka 打包单个可执行exe文件(PyInstaller比nuitka更稳定)