软工作业2:个人项目-论文查重

一、github链接

这个作业属于哪个课程 首页 - 计科22级12班 - 广东工业大学 - 班级博客 - 博客园 (cnblogs.com)
这个作业要求在哪里 个人项目 - 作业 - 计科22级12班 - 班级博客 - 博客园 (cnblogs.com)
这个作业的目标 规范代码编写;学习模块化管理程序功能;学会写单元测试

二、PSP表格

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

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

编码规范

阿里巴巴开发规范手册

3.1 开发环境

操作系统: Windows
编程语言: JDK 20

3.2 开发工具

Maven包管理工具
IDE: IDEA 2023.1.3
性能分析工具: JProfiler 11.1.4

3.3 项目依赖

JUnit测试框架

3.4 算法设计说明

longestCommonSubsequence (LCS) 算法

动态规划:

使用动态规划来计算 LCS。创建一个二维数组 dp,其中 dp[i][j] 表示前 i 个字符和前 j 个字符的 LCS 长度。
遍历两个字符串的每个字符:
1)如果字符相同,则 LCS 长度为 dp[i-1][j-1] + 1。
2)如果字符不同,则 LCS 长度为 Math.max(dp[i-1][j], dp[i][j-1]),即取左边或上边的最大值。

时间复杂度:

LCS 算法的时间复杂度为 O(m × n),其中 m 和 n 分别是两个字符串的长度。

空间复杂度:

空间复杂度为 O(m × n),用于存储动态规划表。如果需要优化空间,可以只保留当前行和上一行的数据。(剪枝)

优点:

1)LCS 算法简单直观,适合用于文本相似度检测。
2)结果能够有效反映文本之间的相似性。

缺点:

1)对于较长的文本,计算复杂度较高,可能导致性能问题。
2)仅依赖于字符匹配,无法捕捉文本的语义信息。

3.5 接口设计与实现过程

类设计与实现过程
1. 文件处理类 (FileHandler)
设计目的

FileHandler 类的主要目的是封装文件操作,以便于读取和写入文本文件。通过将文件操作集中在一个类中,代码变得更加模块化,便于维护和重用。

实现过程
函数1)读取文件:

使用 Files.readAllBytes 方法读取文件内容,并转换为字符串。
处理可能的 IOException,确保文件读取的安全性。

函数2)写入文件:

使用 Files.newBufferedWriter.write 方法将内容写入答案文件,并将输出的答案精确到小数点后两位

2. 相似度计算类 (SimilarityCalculator)
设计目的

SimilarityCalculator 类专注于计算文本之间的相似度,主要采用最长公共子序列(LCS)算法。将相似度计算逻辑与文件处理分开,有助于清晰地划分责任。

实现过程
函数1)计算相似度:

定义 calculateSimilarity 方法,接收两个字符串参数(原始文本和抄袭文本)。
调用 longestCommonSubsequence 方法计算 LCS 长度。
使用公式计算相似度,并通过 DecimalFormat 确保结果保留两位小数。

函数2)LCS 算法实现:

使用两个一维数组 prev 和 curr,将空间复杂度优化为 O(n)。
通过动态规划遍历两个字符串,更新数组以计算 LCS 长度。

3. 主程序类 (PaperPlagiarismChecker)
设计目的

PaperPlagiarismChecker 类作为程序的入口,负责协调文件处理和相似度计算的工作。它集成了其他两个类,形成完整的程序。

实现过程
主方法:

1)在 main 方法中创建 FileHandler 和 SimilarityCalculator 的实例。
2)调用 FileHandler 的 readFile 方法读取原始文本和抄袭文本。
3)调用 SimilarityCalculator 的 calculateSimilarity 方法计算相似度。
4)调用 FileHandler 的 writeFile 方法将相似度结果格式化并写入输出文件,同时打印到控制台。

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

改进计算文本重复率模块性能

LCE算法优化:

-之前的实现:使用了一个二维数组 dp,其大小为 m x n,其中 m 和 n 是两个字符串的长度。这在处理较大字符串时,会占用大量内存。
-优化后的实现:只使用两个一维数组prev和curr,分别存储当前行和上一行的状态。这样,空间复杂度从O(m*n)降低到O(n),显着减少了内存使用。
运行时JProfiler分析

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

以下是以测试 SimilarityCalculator 为例

项目部分单元测试代码
@Test
public void testExactMatch() {
    SimilarityCalculator calc = new SimilarityCalculator();
    double similarity = calc.calculateSimilarity("hello", "hello");
    assertEquals(1.0, similarity, 0.001);
}
@Test
public void testSameCharactersDifferentOrder() {
    SimilarityCalculator calc = new SimilarityCalculator();
    double similarity = calc.calculateSimilarity("abc", "cba");
    assertEquals(0.3333, similarity, 0.001);
}
@Test
public void testPartialMatch() {
    SimilarityCalculator calc = new SimilarityCalculator();
    double similarity = calc.calculateSimilarity("hello", "helicopter");
    assertEquals(0.5333, similarity, 0.001);
}`
构造测试数据的思路:

通过输入两个简单字符串,来测试函数的准确性。包括考虑输入的两个字符串的字符不同、顺序不同、长度不同等多种实际情况。

覆盖率

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

命令行参数不规则,直接判断处理

单元测试样例,错误对应的场景为传入的参数只传了1个,不够3个

posted @ 2024-09-14 23:31  曾繁曦  阅读(10)  评论(0编辑  收藏  举报