其他分享
首页 > 其他分享> > 个人项目

个人项目

作者:互联网

个人项目

软件工程 <网工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