第二次作业--论文查重
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 900 | 600 |
Analysis | 需求分析 (包括学习新技术) | 30 | 60 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 60 | 50 |
Coding | 具体编码 | 300 | 400 |
Code Review | 代码复审 | 20 | 20 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 60 | 60 |
Test Repor | 测试报告 | 60 | 60 |
Size Measurement | 计算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 50 | 50 |
合计 | 1770 | 1460 |
计算模块接口的实现
1.simhash核心算法介绍
2.通过idea底层原码,利用java输入输出流引入文本对象
3.将文本中的文字转换为字符串,利用simhash算法,逐个获取哈希值,汉明距离以及特征值
计算模块接口部分的性能改进
1.性能图
方法调用情况
2.CPU使用情况
3.覆盖率
计算模块部分单元测试展示
1.主模块测试
点击查看代码
package 博客;
import java.text.Format;
public class test {
public static void main(String[] args) {
String origin="E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig.txt";
String[] s={"E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig_0.8_add.txt",
"E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig_0.8_del.txt",
"E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig_0.8_dis_1.txt",
"E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig_0.8_dis_10.txt",
"E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig_0.8_dis_15.txt"};
FileInput fileInput = new FileInput();
SimHashImpl hash1 = new SimHashImpl(fileInput.readString(origin), 64);
hash1.subByDistance(hash1, 3);
// 测试文档1
addTestOne(origin,s,fileInput,hash1);
// 测试文档2
addTestTwo(origin,s,fileInput,hash1);
// 测试文档3
addTestThree(origin,s,fileInput,hash1);
// 测试文档4
addTestFour(origin,s,fileInput,hash1);
// 测试文档5
addTestFive(origin,s,fileInput,hash1);
// 文档路径不存在
addError(origin,s,fileInput,hash1);
}
private static void addError(String origin, String[] s, FileInput fileInput, SimHashImpl hash1) {
SimHashImpl hash2 = new SimHashImpl(fileInput.readString("orig.txt"), 64);
hash2.subByDistance(hash2, 3);
double distance = hash1.getDistance(hash1.getStrSimHash(),hash2.getStrSimHash());
System.out.println("该文章与原文相似度为:"+String.format("%.2f",(100-distance*100/128)) +"%");
}
private static void addTestFive(String origin, String[] s, FileInput fileInput, SimHashImpl hash1) {
SimHashImpl hash2 = new SimHashImpl(fileInput.readString(s[4]), 64);
hash2.subByDistance(hash2, 3);
double distance = hash1.getDistance(hash1.getStrSimHash(),hash2.getStrSimHash());
System.out.println("该文章与原文相似度为:"+String.format("%.2f",(100-distance*100/128)) +"%");
}
private static void addTestFour(String origin, String[] s, FileInput fileInput, SimHashImpl hash1) {
SimHashImpl hash2 = new SimHashImpl(fileInput.readString(s[3]), 64);
hash2.subByDistance(hash2, 3);
double distance = hash1.getDistance(hash1.getStrSimHash(),hash2.getStrSimHash());
System.out.println("该文章与原文相似度为:"+String.format("%.2f",(100-distance*100/128)) +"%");
}
private static void addTestThree(String origin, String[] s, FileInput fileInput, SimHashImpl hash1) {
SimHashImpl hash2 = new SimHashImpl(fileInput.readString(s[2]), 64);
hash2.subByDistance(hash2, 3);
double distance = hash1.getDistance(hash1.getStrSimHash(),hash2.getStrSimHash());
System.out.println("该文章与原文相似度为:"+String.format("%.2f",(100-distance*100/128)) +"%");
}
private static void addTestTwo(String origin, String[] s, FileInput fileInput, SimHashImpl hash1) {
SimHashImpl hash2 = new SimHashImpl(fileInput.readString(s[1]), 64);
hash2.subByDistance(hash2, 3);
double distance = hash1.getDistance(hash1.getStrSimHash(),hash2.getStrSimHash());
System.out.println("该文章与原文相似度为:"+String.format("%.2f",(100-distance*100/128)) +"%");
}
private static void addTestOne(String origin, String[] s, FileInput fileInput, SimHashImpl hash1) {
SimHashImpl hash2 = new SimHashImpl(fileInput.readString(s[0]), 64);
hash2.subByDistance(hash2, 3);
double distance = hash1.getDistance(hash1.getStrSimHash(),hash2.getStrSimHash());
System.out.println("该文章与原文相似度为:"+String.format("%.2f",(100-distance*100/128)) +"%");
}
}
点击查看代码
package 博客;
import java.io.*;
public class FileInput {
public String readString(String FI){
int len=0;
// 对字符串进行多次修改,并且不会产生新的未产生的使用对象
// 创建一个
StringBuffer str=new StringBuffer("");
// File类以抽象类的方式代表文件名和目录路径名,用于文件和目录的创建,查找和删除
// FI代表需要插入文件的目录
// file获取传过来的路径名,获取文件对象
File file = new File(FI);
// try{}当中利用readline来读取文件中的内容
try {
// FileInputStream()用于从文件中读取数据,他的对象用关键字new来创建
// 也可以使用一个文件对象来创建一个输入流队形对象来读取文件
// File f=new File("C:/java/hello");
// InputStream in =new FileInputStream(f);
FileInputStream fileInputStream = new FileInputStream(file);
// 将读取文件中的内容赋给对象bufferedReader
// BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line=null;
// bufferedReader.readLine()从文本对象中读取一行数据,见名知意,就是一行一行读取
while((line=bufferedReader.readLine())!=null){
if (len!=0){
// 除了第一行,每一行都需要换行,str为StringBuffer类,多次添加数据
str.append("\r\n"+line);
// str.append(line);
}else {
str.append(line);
}
len++;
}
// System.out.println(len);
// 关闭此文件输入流并释放与此流有关的所有系统资源
bufferedReader.close();
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
// return str;
}
public static void main(String[] args) {
//
FileInput fileInput = new FileInput();
String s = fileInput.readString("E:\\文档\\WeChat Files\\wxid_my9r0rap70vc22\\FileStorage\\File\\2024-03\\测试文本\\orig.txt");
System.out.println(s);
}
}
点击查看代码
public BigInteger simHash() {
// 定义特征向量/数组
int[] v = new int[this.hashbits];
StringTokenizer stringTokens = new StringTokenizer(this.tokens);
while (stringTokens.hasMoreTokens()) {
String temp = stringTokens.nextToken();
//2、将每一个分词hash为一组固定长度的数列.比如 64bit 的一个整数.
BigInteger t = this.hash(temp);
for (int i = 0; i < this.hashbits; i++) {
BigInteger bitmask = new BigInteger("1").shiftLeft(i);
// 3、建立一个长度为64的整数数组(假设要生成64位的数字指纹,也可以是其它数字),
// 对每一个分词hash后的数列进行判断,如果是1000...1,那么数组的第一位和末尾一位加1,
// 中间的62位减一,也就是说,逢1加1,逢0减1.一直到把所有的分词hash数列全部判断完毕.
if (t.and(bitmask).signum() != 0) {
v[i] += 1;
} else {
v[i] -= 1;
}
}
}
BigInteger fingerprint = new BigInteger("0");
StringBuffer simHashBuffer = new StringBuffer();
for (int i = 0; i < this.hashbits; i++) {
// 4、最后对数组进行判断,大于0的记为1,小于等于0的记为0,得到一个 64bit 的数字指纹/签名.
if (v[i] >= 0) {
fingerprint = fingerprint.add(new BigInteger("1").shiftLeft(i));
simHashBuffer.append("1");
}else{
simHashBuffer.append("0");
}
}
this.strSimHash = simHashBuffer.toString();
setStrSimHash(strSimHash);
// System.out.println(this.strSimHash + " length " + this.strSimHash.length());
return fingerprint;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步