个人项目
作者:互联网
个人项目
软件工程 | <网工1934> |
---|---|
作业要求 | <作业要求连接> |
作业目标:完成论文查重项目,实现并经过测试后上传到GitHub | <Github连接> |
PSP表格
PSP2.1 | Personal SoftwareProcess Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 35 |
Estimate | 估计这个任务需要多少时间 | 80 | 100 |
Development | 开发 | 1080 | 1200 |
Analysis | 需求分析(包括学习新技术) | 180 | 240 |
Design Spec | 生成设计文档 | 80 | 60 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
Design | 具体设计 | 120 | 100 |
Coding | 具体编码 | 300 | 420 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 180 | 280 |
Reporting | 报告 | 240 | 300 |
Test Report | 测试报告 | 60 | 80 |
Size Measurement | 计算工作量 | 60 | 60 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 120 | 120 |
合计 | 2650 | 3115 |
需求分析
题目:论文查重
需求:
1.读取原文文件,抄袭版论文文件以及把结果输出到指定文件中
2.把原文文件内容和抄袭版论文文件内容进行对比,得出重复率
模块借口设计和实现过程
思路:
关键函数分析与实现
在上网查阅资料之后,发现有两类用的比较多的函数
一类是利用TF-IDF与余弦相似性
另一类是利用simhash与hamming距离来判断相似度
本项目是利用后者进行相似度判断的
参考链接
整体流程:
这种方法有5个步骤:
1.分词 将一个句子分成特征词
2.hash 提取词语的hash值
3.加权 将提取出来的hash值进行加权运算
4.合并 把各单词的加权值进行累加
5.降维 把累加后的序列串降为变成0 1串
原理图:
通过对比不同文本内容的0 1串算出hamming距离,从而得出相似度
1.主要实现类
工具类:
TxTIo:对用户输入的路径进行文件的读取以及写入
SimHash:计算SimHash的值
1、分词
List<String> keywordList = HanLP.extractKeyword(str,str.length());
2.获得hash值
int size = keywordList.size();
int i = 0;
for(String keyword : keywordList){
//获取hash值
String keywordHash = getHash(keyword);
if(keywordHash.length()<128){
//若hash值低于128位,则补0,补全128位
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'){
v[j] += (10 - (i / (size / 10)));
}
else{
v[j] -= (10 - (i / (size/10)));
}
}
i++;
}
4.降维
String simHash = "";
for(int j=0;j<v.length;j++){
//从高位遍历到低位
if(v[j]<=0){
simHash += "0";
}else{
simHash += "1";
}
}
Hamming:计算Hamming距离
有两个方法
1.输入两个simHash序列,对比得到hamming距离
public static int getHammingDistance(String simHash1,String simHash2){
int distance = 0;
if(simHash1.length() != simHash2.length()){
//如果传入的hash长度不同,出错,返回-1
distance = -1;
}else{
for(int i =0;i<simHash1.length();i++){
//对每一位进行比较,算出hamming长度
if(simHash1.charAt(i)!=simHash2.charAt(i)){
distance++;
}
}
}
return distance;
}
2.通过hamming距离算出相似度
public static double getSimilarity(String simHash1,String simHash2){
//通过simHash1和simHash2获得海明距离
int distance = getHammingDistance(simHash1,simHash2);
//通过海明距离算出相似度,并返回
return 0.01 * (100 - (double)distance * 100 /128);
}
ShortStringException:处理文本内容过短(或不存在)的异常类
主类:
MainPaperCheck:用以用户输入三个文件的路径,并利用工具类实现查重功能
性能分析
从性能分析上可以得出调用次数最多的是com.hakcs.hanlp提供的接口
单元测试
使用JUnit4进行单元测试
TxtIoTest类的测试
@Test
public void readTxt() {
//路径存在,正常读取
String str = TxtIo.readTxt("D:\\works\\txttest\\other.txt");
String[] Strings = str.split(" ");
for(String string : Strings){
System.out.println(string);
}
}
@Test
public void writeTxt() {
//路径存在,正常写入
double[] elem = {0.1111,0.2222,0.3333,0.4444,0.5555};
for(int i = 0;i<elem.length;i++){
TxtIo.writeTxt(elem[i],"D:\\works\\txttest\\test.txt","name1","name2");
}
}
@Test
public void readTxtfail(){
//路径不存在,读取失败
String str = TxtIo.readTxt("D:\\works\\txttest\\abc.txt");
}
@Test
public void writeTxtfail(){
double[] elem = {0.11,0.22,0.33,0.44,0.55};
for(int i=0;i<elem.length;i++){
TxtIo.writeTxt(elem[i],"D:\\works\\txtest\\ans.txt","name1","name2");
}
}
}
正常结果:
代码覆盖率:
SimHash类测试
@Test
public void getHash() {
String[] strings = {"超新星啊","更加闪耀吧","在星降之夜","称赞红月"};
for(String string:strings){
String stringHash = SimHash.getHash(string);
System.out.println(stringHash.length());
System.out.println(stringHash);
}
}
@Test
public void getSimHash() {
String str0 = TxtIo.readTxt("D:\\works\\txttest\\orig.txt");
String str1 = TxtIo.readTxt("D:\\works\\txttest\\orig_0.8_add.txt");
System.out.println(SimHash.getSimHash(str0));
System.out.println(SimHash.getSimHash(str1));
}
}
测试结果:
代码覆盖率:
Hamming类测试
@Test
public void getHammingDistance() {
//获得hamming距离
String str0 = TxtIo.readTxt("D:\\works\\txttest\\orig.txt");
String str1 = TxtIo.readTxt("D:\\works\\txttest\\orig_0.8_add.txt");
int distance = Hamming.getHammingDistance(SimHash.getSimHash(str0),SimHash.getSimHash(str1));
System.out.println("hamming distance:" + distance);
System.out.println("相似度: " + (100-distance * 100/ 128) + "%");
}
@Test
public void getHammingDistancefail() {
//测试str0和str1长度不等的情况
String str0 = "101010";
String str1 = "1010101";
int distance = Hamming.getHammingDistance(str0,str1);
System.out.println("hamming distance:" + distance);
}
@Test
public void getSimilarity() {
String str0 = TxtIo.readTxt("D:\\works\\txttest\\orig.txt");
String str1 = TxtIo.readTxt("D:\\works\\txttest\\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("hamming distance:" + distance);
System.out.println("相似度: " + similarity);
}
测试结果:
正常输入
hash距离不一样
代码覆盖率:
项目程序功能测试
标签:distance,String,个人,项目,int,System,println,SimHash 来源: https://www.cnblogs.com/Enternal9/p/15257751.html