论文查重程序——第一次个人作业

作业简介

这个作业属于哪个课

软件工程

这个作业要求在哪里

作业要求

这个作业的目标

论文查重算法设计+项目管理+单元测试+性能测试及调优

作业代码链接

GitHub链接

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

整体流程

  1. 通过命令行获取文件路径,读取相应的文件内容
  2. 去除标点符号,将完整的文本作为一个字符串
  3. 通过算法计算重复字数和重复率
  4. 将结果写入相应的文件中(若无相应的文件则创建)

项目的包结构

java论文查重源码 论文查重编程_java论文查重源码

项目中的类及其功能

  1. Main:程序入口
  2. CalculatorUtil:核心算法相关的工具类
    1)calculate():计算重复字数
  3. FileUtil:文件操作工具类
    1)readFromFile():读取文件内容
    2)writeInFile():将结果写入文件中
    3)createFileIfNotExist():确保输出的目标文件存在
    4)getPercentFormat():转换重复率
  4. File:论文文件模型

各类之间的关系图

java论文查重源码 论文查重编程_软件工程_02

算法分析

程序算法思路

程序计算重复率的方法是先计算出两篇论文中重复的字数,再除以对比论文的总字数,即:

重复率=重复字数/对比论文总字数

核心算法

其中计算重复字数的核心算法的是用动态规划实现最长公共子序列(LCS)算法,其递推式如下图所示:

java论文查重源码 论文查重编程_Test_03

空间优化

由于C[i,j]的值总是建立在二维数组第i行某一列元素或者第i-1行某一列元素基础上的,如果不需要求解最长公共子序列是什么,只需要求解其长度,那么可以建立一个2*n的滚动数组代替n*m的数组来实现空间优化,这种方法只需要用到两个数组的数据,通过两个数组的不断交换实现m*n的数组功能。

代码实现

java论文查重源码 论文查重编程_java论文查重源码_04

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

java论文查重源码 论文查重编程_Test_05

java论文查重源码 论文查重编程_java论文查重源码_06

类的内存消耗

java论文查重源码 论文查重编程_Test_07

时间

java论文查重源码 论文查重编程_Test_08

CPU Load

java论文查重源码 论文查重编程_Test_09

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

测试程序入口

测试代码

package org.ggxian.papercheck;

import junit.framework.TestCase;
import org.ggxian.papercheck.Main;
import org.junit.Assert;
import org.junit.Test;

/**
 * @author GGXian
 * @project 个人作业
 * @createTime 2020/9/25 0:21
 * @description Main测试类
 **/
public class TestMain {
    /**
     * 测试源文件路径为null的情况
     */
    @Test
    public void testForOriginalArticleNull(){
//        Assert.assertThrows()
        Main.main(new String[]{null,"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_add.txt","D:\\1.txt"});
    }


    /**
     * 测试对比文件路径为null的情况
     */
    @Test
    public void testForPlagiarismArticleNull(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig.txt",null,"D:\\1.txt"});
    }

    /**
     * 测试结果输出文件路径为null的情况
     */
    @Test
    public void testForResultNull(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_add.txt",null});
    }


    /**
     * 测试路径不存在的情况
     */
    @Test
    public void testForNotExistFile(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_add.txt",null});
    }


    /**
     * 测试输入对比的文件内容为空的情况
     */
    @Test
    public void testForEmpty(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_add.txt","D:\\1.txt"});
    }

    /**
     * 测试对比orig_0.8_add.txt
     */
    @Test
    public void testForAdd(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_add.txt","D:\\1.txt"});
    }


    /**
     * 测试对比orig_0.8_del.txt
     */
    @Test
    public void testForDel(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_del.txt","D:\\1.txt"});
    }

    /**
     * 测试对比orig_0.8_dis_1.txt.txt
     */
    @Test
    public void testForDis1(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_dis_1.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_dis_1.txt","D:\\1.txt"});
    }

    
    /**
     * 测试对比orig_0.8_dis_10.txt
     */
    @Test
    public void testForAdd10(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例orig_0.8_dis_1.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例orig_0.8_dis_10.txt","D:\\1.txt"});
    }


    /**
     * 测试对比orig_0.8_dis_15.txt
     */
    @Test
    public void testForDis15(){
        Main.main(new String[]{"C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_dis_1.txt","C:\\Users\\huawei\\Desktop\\软件工程导论\\论文查重样例\\orig_0.8_dis_15.txt","D:\\1.txt"});
    }
}

测试结果

java论文查重源码 论文查重编程_软件工程_10

覆盖率

java论文查重源码 论文查重编程_软件工程_11

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

IO异常

代码处理

java论文查重源码 论文查重编程_java论文查重源码_12

输入空值异常

代码处理

package org.ggxian.papercheck.component;

/**
 * @author GGXian
 * @project 个人作业
 * @createTime 2020/9/25 21:20
 * @description 自定义异常
 **/
public class EnterNullException extends Exception {
    public EnterNullException(){
        
    }

    public EnterNullException(String message){
        super(message);
    }
}

java论文查重源码 论文查重编程_Desktop_13

测试

java论文查重源码 论文查重编程_java论文查重源码_14

java论文查重源码 论文查重编程_Desktop_15

java论文查重源码 论文查重编程_软件工程_16

PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

25

20

· Estimate

· 估计这个任务需要多少时间

25

20

Development

开发

725

705

· Analysis

· 需求分析 (包括学习新技术)

240

350

· Design Spec

· 生成设计文档

15

20

· Design Review

· 设计复审

30

25

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

20

30

· Design

· 具体设计

60

50

· Coding

· 具体编码

240

120

· Code Review

· 代码复审

60

40

· Test

· 测试(自我测试,修改代码,提交修改)

60

70

Reporting

报告

180

229

· Test Report

· 测试报告

30

45

· Size Measurement

· 计算工作量

30

34

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

120

150

· 合计

930

954