第一次个人编程作业

第一次个人编程作业

这个作业属于哪个课程 软件工程
这个作业要求在哪里 个人项目作业
这个作业的目标 设计论文查重算法+应用PSP表格+单元测试+ JProfiler 性能分析+Git管理

一、GitHub

二、PSP表格

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

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

1、 算法原理

  • 参考资料:simhash算法及原理简介

  • 采用SimHash算法:SimHash算法分为 5 个步骤:分词、hash、加权、合并、降维。

  • 整体算法流程图:

  • 算法独到之处:

    • SimHash本身属于一种局部敏感哈希算法,它产生的hash签名在一定程度上可以表征原内容的相似度

    • SimHash算法的签名值除了提供原始内容是否相等的信息外,还能额外提供不相等的原始内容的差异程度的信息。

    • 相较传统的hash和余弦相似度算法,SimHash算法相对简单、效果又好

2、项目结构设计:

3、类和方法设计

  • IOText 类:读取或写入文件

    • getText():传入 txt 路径读取 txt 文件,返回读取到的内容
    • writeText(): 传入输出内容和输出路径,向指定路径写入指定内容
  • Main 类:调用函数并输出结果

    • main(): 主函数,传入参数,输出结果
    • Test1(): 传入测试文件路径和输出路径,调用函数输出结果,并向输出路径写入结果
  • SimHash 类:计算文本相似度的核心算法工具类

    • simHash(): 程序的关键函数,将文本进行分词,并得到一个 simHash 值。
    • hash(): 计算每个分词对应的 hash 值。
    • hammingDistance(): 根据 SimHash 算法算出文档的签名值。
    • getDistance(): 计算两个签名的海明距离,海明距离越低,相似度越高
    • subByDistance(): 计算海明距离在范围内的各块签名的 hash 值,通常认为距离在3以内的视为重复
  • PathInput 类:分别输入测试文件路径和输出路径,输出结果

  • MyTest 类: 测试类

  • 关系流程图:

  • 关键函数simHash()流程图:

四、计算模块接口部分的性能改进

  1. 内存占用情况:

  2. 类占用情况:

  3. CPU负载

五、计算模块部分单元测试展示

1.白盒测试:

​ 对原文件的添加、删除、修改、文件不存在或路径错误、文件内容为空等进行测试。

2.测试用例代码:

package paperpass;

import org.junit.jupiter.api.Test;

class MyTest {
    String origin = "text2\\orig.txt";
    String[] txtPath={
            "text2\\orig_0.8_add.txt",
            "text2\\orig_0.8_del.txt",
            "text2\\orig_0.8_dis_1.txt",
            "text2\\orig_0.8_dis_10.txt",
            "text2\\orig_0.8_dis_15.txt",
    };

    String[] htmlPath={
            "text\\orig_0.8_del.txt",
            "text\\orig_0.8_dis_1.txt", "text\\orig_0.8_dis_10.txt",
            "text\\orig_0.8_dis_15.txt",};

    String outPath = "output.txt";
    Main txtCheck1 = new Main();

    /**
    *文本测试:
     *原文件的添加
    */
    @Test
    public void addTest(){
        txtCheck1.Test1(origin, txtPath[0],outPath);
    }

    /**原文件的删除*/
    @Test
    public void delTest(){
        txtCheck1.Test1(origin, txtPath[1],outPath);
    }

    /**原文件的修改*/
    @Test
    public void dis_1Test(){
        txtCheck1.Test1(origin, txtPath[2],outPath);
    }

    @Test
    public void dis_10Test(){
        txtCheck1.Test1(origin, txtPath[3],outPath);
    }

    @Test
    public void dis_15Test(){
        txtCheck1.Test1(origin, txtPath[4],outPath);
    }

    /**
     * 对 html 进行测试
     * */
    @Test
    public void html1Test(){
        txtCheck1.Test1(origin, htmlPath[1],outPath);
    }

    @Test
    public void html2Test(){
        txtCheck1.Test1(origin, htmlPath[3],outPath);
    }

    /**html 和 html 进行测试*/
    @Test
    public void html3Test(){
        txtCheck1.Test1(htmlPath[0], htmlPath[3],outPath);
    }

    /**
     * 测试文本路径错误或不存在
     * */
    @Test
    public void txtPathWrongTest(){
        txtCheck1.Test1("text\\orig_del.txt","text2\\orig_dis_15.txt" ,outPath);
    }

    /**
     * 输出文件路径错误或不存在
     * */
    @Test
    public void outPathWrongTest(){
        txtCheck1.Test1("text2\\orig_0.8_del.txt","text2\\orig_0.8_dis_10.txt","out_put.txt");
    }

    /**
     * 测试文本为空
     * */
    @Test
    public void emptyTest(){
        txtCheck1.Test1("text2\\empty.txt","text2\\orig_0.8_dis_10.txt","output.txt");
    }

3.运行结果:

4.耗时:

​ 可以看出,测试 html 耗时比 txt 文本的耗时久

5.测试覆盖率:

六、计算模块部分异常处理说明

1.测试文件不存在或路径输入错误

  • 部分代码

  • 测试用例

  • 测试结果

2.输出文件路径错误或不存在

  • 部分代码

  • 测试用例

  • 测试结果

3.测试文件为空

  • 部分代码

  • 测试用例

  • 测试结果

posted @ 2021-09-19 21:49  LianWL824  阅读(46)  评论(0)    收藏  举报