个人项目:论文查重

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834/
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834/homework/11146
这个作业的目标 个人完成论文查重项目

一、GitHub链接:

my github

二、PSP表格

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

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

1.算法原理

  参考文章:https://www.cnblogs.com/qdhxhz/p/9484274.html

(1)可通过向量来计算相识度公式。

(2)余弦值越接近1,也就是两个向量越相似,这就叫"余弦相似性",
余弦值越接近0,也就是两个向量越不相似,也就是这两个字符串越不相似。

2、案例理论知识

  举一个例子来说明,用上述理论计算文本的相似性。为了简单起见,先从句子着手。

  句子A:这只皮靴号码大了。那只号码合适。
  句子B:这只皮靴号码不小,那只更合适。

  怎样计算上面两句话的相似程度?
  基本思路是:如果这两句话的用词越相似,它们的内容就应该越相似。因此,可以从词频入手,计算它们的相似程度。

  第一步,分词。
  句子A:这只/皮靴/号码/大了。那只/号码/合适。
  句子B:这只/皮靴/号码/不/小,那只/更/合适。
  第二步,计算词频。(也就是每个词语出现的频率)
  句子A:这只1,皮靴1,号码2,大了1。那只1,合适1,不0,小0,更0
  句子B:这只1,皮靴1,号码1,大了0。那只1,合适1,不1,小1,更1
  第三步,写出词频向量。
  句子A:(1,1,2,1,1,1,0,0,0)
  句子B:(1,1,1,0,1,1,1,1,1)

  第四步:运用上面的公式:计算如下:


计算结果中夹角的余弦值为0.81非常接近于1,所以,上面的句子A和句子B是基本相似的

3.类图

4.独到之处:

        运行速度还是比较快的,基本可以在3s以内完成

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

1.使用SonarLint发现警告并消除

  消除后:

2.性能分析:

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

1.部分代码:

  String[] paths = {
        "src/test/testcase/orig.txt",
        "src/test/testcase/empty.txt",
        "src/test/testcase/orig_0.8_add.txt",
        "src/test/testcase/orig_0.8_del.txt",
        "src/test/testcase/orig_0.8_dis_1.txt",
        "src/test/testcase/orig_0.8_dis_10.txt",
        "src/test/testcase/orig_0.8_dis_15.txt",
        "src/test/testcase/unknown.txt",
        "src/test/testcase/orig_0.8_dis_16.txt"
};
 /**
 * 测试 文本为空文本的情况
 */
@Test
public void testForEmpty(){
    try {
        Main.process(paths[0],paths[1],"src/test/result/testEmptyResult.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试 输入的对比文本路径参数为错误参数的情况
 */
@Test
public void testForWrongOriginArgument(){
    try {
        Main.process("src/test/testcase/123.txt",paths[0],"src/test/result/testAddResult.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试20%文本添加情况:orig_0.8_add.txt
 */
@Test
public void testForAdd(){
    try {
        Main.process(paths[0],paths[2],"src/test/result/testAddResult.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试20%文本删除情况:orig_0.8_del.txt
 */
@Test
public void testForDel(){
    try {
        Main.process(paths[0],paths[3],"src/test/result/testDelResult.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试20%文本乱序情况:orig_0.8_dis_1.txt
 */
@Test
public void testForDis1(){
    try {
        Main.process(paths[0],paths[4],"src/test/result/testDis1Result.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}



/**
 * 测试20%文本乱序情况:orig_0.8_dis_10.txt
 */
@Test
public void testForDis10(){
    try {
        Main.process(paths[0],paths[5],"src/test/result/testDis10Result.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试20%文本乱序情况:orig_0.8_dis_15.txt
 */
@Test
public void testForDis15(){
    try {
        Main.process(paths[0],paths[6],"src/test/result/testDis15Result.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试相同文本:orig.txt
 */
@Test
public void testForSame(){
    try {
        Main.process(paths[0],paths[0],"src/test/result/testSameResult.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}

/**
 * 测试未知文本:unknown.txt
 */
@Test
public void testUnknown(){
    try {
        Main.process(paths[0],paths[7],"src/test/result/testUnknown.txt");
    }
    catch (Exception e) {
        e.printStackTrace();
        // 如果抛出异常,证明测试失败,没有通过,没通过的测试计数在Failures中
        Assert.fail();
    }
}                  

2.测试思路:

  思路来源于命令行测试代码:Java: java -jar main.jar [原文文件] [抄袭版论文的文件] [答案文件]
  设定三份文件路径,以文本之间不同的比对,来达到测试代码的目的

3.测试覆盖率

  • 首次测试:

    显然,测试代码覆盖率并不高,还有很多改进的空间

  • 尝试改进utils,结果:

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

1.IOException

  采用空文本与原文对比测试

2.FileNotFoundException

  采用路径错误的文本与原文对比测试

posted @ 2020-09-25 00:42  金鱼同学  阅读(181)  评论(0编辑  收藏  举报