个人第一次编程作业

发布时间:2022-07-05 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了个人第一次编程作业脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

一、简述

Documents Content
作业所属的课程 班级地址
作业要求 第一次编程作业要求

二、项目地址

个人GIThub仓库地址

三、项目需求

论文查重

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

  • 原文:今天是星期天,天气晴,今天晚上我要去看电影
  • 抄袭之后的文本:今天是周天,天气晴朗,我晚上要去看影。

要求输入输出采用文件输入输出,规范如下:

  • 命令行参数给出:论文原文的文件的绝对路径
  • 命令行参数给出:抄袭版论文的文件的绝对路径
  • 命令行参数给出:输出的答案文件的绝对路径

四、程序开发环境

五、PSP表格(预计花费时间)

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

六、计算模块接口的设计与实现过程

1.接口主要实现的功能:通过求出两个文本内容的海明距离来求出其相似度

2.simHash算法

simHash的主要思想是降维,将高维的特征向量映射成低维的特征向量,通过两个向量的Hamming Distance来确定文章是否重复或者高度近似。其中,Hamming Distance,又称汉明距离,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。也就是说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:1011101 与 1001001 之间的汉明距离是 2。至于我们常说的字符串编辑距离则是一般形式的汉明距离。如此,通过比较多个文档的simHash值的海明距离,可以获取它们的相似度。

simHash流程主要有五个步骤:分词、hash、加权、合并、降维。 分词:给定一段语句,进行分词,得到有效的特征向量,然后为每一个特征向量设置1-5等5个级别的权重(如果是给定一个文本,那么特征向量可以是文本中的词,其权重可以是这个词出现的次数)。

个人第一次编程作业

hash:通过hash函数计算各个特征向量的hash值,hash值为二进制数01组成的n-bit签名。

个人第一次编程作业

加权:在hash值的基础上,给所有特征向量进行加权,即W = Hash * weight,且遇到1则hash值和权值正相乘,遇到0则hash值和权值负相乘。 合并:将上述各个特征向量的加权结果累加,变成只有一个序列串。

个人第一次编程作业

降维:对于n-bit签名的累加结果,如果大于0则置1,否则置0,从而得到该语句的simhash值,最后我们便可以根据不同语句simhash的海明距离来判断它们的相似度。

个人第一次编程作业

  • 可以参考以下文章:https://blog.csdn.net/lengye7/article/details/79789206

3.海明距离计算

海明距离是序列相同位置上数据不同的个数,比如abc和acb,海明距离是第二位和第三位不同,海明距离是2。 具体实现:

个人第一次编程作业

  • 参考文章:https://www.cnbLOGs.COM/chulin/p/9927110.htML

七、性能分析

个人第一次编程作业

可以看出消耗较多的函数为用在浮点计算中的Float、hanlp包所提供的函数等

八、单元测试

1.主测试方法

package libgem.mainclass;

import libgem.utils.SimHash;
import libgem.utils.Txt_TO_String;
import libgem.utils.Utils_Hamming;
import org.junit.Test;

public class TestMainClass {
    @Test
    // 测试原文本和其他所有抄袭文本的查重
    public void TestforAllTxt(){
        String[] strings = new String[6];
        strings[0] = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        strings[1] = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_add.txt");
        strings[2] = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_del.txt");
        strings[3] = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_dis_1.txt");
        strings[4] = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_dis_10.txt");
        strings[5] = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_dis_15.txt");
    }

    @Test
    // 测试原文本和原文本比较的查重率
    public void origEqualTest(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String compTxt = "E:/3119005458SoftW/test/equTxt.txt";
        double equal = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        Txt_TO_String.txt_write_String(equal, compTxt);
    }

    @Test
    // 测试orig和orig_0.8_add查重率
    public void origAddTest(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_add.txt");
        String compTxt = "E:/3119005458SoftW/test/addTxt.txt";
        double compAdd = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        Txt_TO_String.txt_write_String(compAdd, compTxt);
    }

    @Test
    // 测试orig和orig_0.8_del查重率
    public void origDelTest(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_del.txt");
        String compTxt = "E:/3119005458SoftW/test/delTxt.txt";
        double compDel = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        Txt_TO_String.txt_write_String(compDel, compTxt);
    }

    @Test
    // 测试orig和orig_0.8_dis_1查重率
    public void origDis1Test(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_dis_1.txt");
        String compTxt = "E:/3119005458SoftW/test/dis1Txt.txt";
        double compDis1 = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        Txt_TO_String.txt_write_String(compDis1, compTxt);
    }

    @Test
    // 测试orig和orig_0.8_dis_10查重率
    public void origDis10Test(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_dis_10.txt");
        String compTxt = "E:/3119005458SoftW/test/dis10Txt.txt";
        double compDis10 = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        Txt_TO_String.txt_write_String(compDis10, compTxt);
    }

    @Test
    // 测试orig和orig_0.8_dis_15查重率
    public void origDis15Test(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/orig_0.8_dis_15.txt");
        String compTxt = "E:/3119005458SoftW/test/dis15Txt.txt";
        double compDis15 = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        Txt_TO_String.txt_write_String(compDis15, compTxt);
    }

}

个人第一次编程作业

2.Hamming距离测试

public class TestForHamming {

    @Test
    public void testHammingDistance(){
        String str0 =  Txt_TO_String.getStringForTxt("E:/3119005458/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458/test/orig_0.8_add.txt");
        int distance = Utils_Hamming.hammingDistance(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        System.out.println("海明距离:" + distance);
        System.out.println("相似度" + (100 - distance * 100 / 128) + "%");
    }

    @Test
    public void hammingDistanceException(){
        // 如果出现两个获取的字符串长度不一样的情况
        String str0 = "10101010";
        String str1 = "1010101";
        System.out.println(Utils_Hamming.hammingDistance(str0, str1));
    }

    @Test
    public void SimilarityTest(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458/test/orig_0.8_add.txt");
        int hammingDistance = Utils_Hamming.hammingDistance(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        double similarity = Utils_Hamming.similarity(SimHash.getSimHash(str0), SimHash.getSimHash(str1));
        System.out.println("str0和str1之间的海明距离为:" + hammingDistance);
        System.out.println("str0和str1的相似度为:" + similarity);
    }

}

个人第一次编程作业

3.simHash流程测试

public class TestForSimHash {

    @Test
    public void TestForGetHash(){
        String[] strings = {"广东", "工业" , "大学", "计算机学院", "信息", "安全"};
        for(String string : strings){
            String hash_String = SimHash.getHash_for_String(string);
            System.out.println(hash_String.length());
            System.out.println(hash_String);
        }
    }

    @Test
    public void TestForSimHash(){
        String str0 = Txt_TO_String.getStringForTxt("E:/3119005458/test/orig.txt");
        String str1 = Txt_TO_String.getStringForTxt("E:/3119005458/test/orig_0.8_add.txt");
        System.out.println(SimHash.getSimHash(str0));
        System.out.println(SimHash.getSimHash(str1));
    }
}

个人第一次编程作业

4.对文本内容输入输出测试

public class TestForTxt_TO_String {

    @Test
    public void TestFor_getTxt(){
        //  如果文件路径存在的话,则正常读取文件
        String str = Txt_TO_String.getStringForTxt("E:/3119005458/test/orig.txt");
        String[] strings = str.split(" "); // 切割文本
        for (String string : strings){
            System.out.println(string);
        }
    }

    @Test
    public void TestFor_getTxt_Fail(){
        // 如果读取文件的路径不存在的话,则读取失败
        String str = Txt_TO_String.getStringForTxt("E:/3119005458SoftW/test/fail.txt");
    }

    @Test
    public void write_Txt_Test(){
        // 当路径存在时,测试查重率的写入是否正常
        double[] rate_rechecking = {0.10, 0.99, 0.24, 0.34, 0.67};
        for (int i = 0; i < rate_rechecking.length; i++) {
            Txt_TO_String.txt_write_String(rate_rechecking[i], "E:/3119005458SoftW/test/result.txt");
        }
    }

    @Test
    public void write_txt_test_fail(){
        // 路径不存在时,对数据写入错误的测试
        double[] rate_recheck = {0.10, 0.26, 0.45, 0.25, 0.57};
        for (int i = 0; i < rate_recheck.length; i++) {
            Txt_TO_String.txt_write_String(rate_recheck[i], "E:/3119005458SoftW/test/fail.txt");
        }
    }
}

个人第一次编程作业

5.测试结果文件

个人第一次编程作业

个人第一次编程作业

九、异常处理

由于导入的外部hanLP依赖包只支持长度为200以上的关键字,所以当文本比较短的时候会报出ShortStringException的异常。

异常处理模块:

public class TestForShortStringException {

    @Test
    public void test_for_shortString(){
        // 测试hanlp包在str.length() < 200  的情况
        System.out.println(SimHash.getSimHash("广东工业大学"));
    }
}

模块单元测试

个人第一次编程作业

十、PSP表格(程序设计完成之后)

由于本人的Java代码开发技术很有限,花了比想象中多得多的时间,通过这一次的作业,更加的了解在开发软件时需要注意的问题

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

脚本宝典总结

以上是脚本宝典为你收集整理的个人第一次编程作业全部内容,希望文章能够帮你解决个人第一次编程作业所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。