软件工程第二次作业-第一次个人编程作业
个人编程作业
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 软件工程 |
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 训练个人项目软件开发能力,学会使用性能测试工具和实现单元测试优化程序 |
代码仓库:https://github.com/FZ688/3123004177-TextCheck
releases:https://github.com/FZ688/3123004177-TextCheck/releases/tag/V1.0.0
一、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 35 | 20 |
Estimate | 估计这个任务需要多少时间 | 35 | 20 |
Development | 开发 | 425 | 400 |
Analysis | 需求分析 (包括学习新技术) | 120 | 100 |
Design Spec | 生成设计文档 | 60 | 50 |
Design Review | 设计复审 | 15 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 30 |
Design | 具体设计 | 60 | 70 |
Coding | 具体编码 | 120 | 100 |
Code Review | 代码复审 | 30 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 50 |
Reporting | 报告 | 80 | 90 |
Test Report | 测试报告 | 45 | 50 |
Size Measurement | 计算工作量 | 10 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 25 | 20 |
合计 | 540 | 560 |
二、计算模块接口的设计与实现
1. 代码组织结构
本论文查重程序主要包含5个核心类,它们的关系和职责如下:
Main
:程序入口,处理命令行参数,协调各模块工作SimilarityCalculator
:核心计算类,实现相似度计算逻辑TextProcessor
:文本预处理工具类,负责文本清洗和分词FileHandler
:文件处理工具类,负责文件的读写操作StringUtils
:字符串工具类,实现编辑距离计算
类之间的关系如图所示:
2. 核心算法设计
本程序采用两种相似度算法加权融合的方式计算文本重复率:
-
余弦相似度:基于词频向量计算
- 将文本分词后构建词频向量
- 计算两个向量的余弦夹角作为相似度度量
-
编辑距离相似度:基于Levenshtein距离
- 计算两个文本之间的最小编辑操作数(插入、删除、替换)
- 将编辑距离转换为相似度(1 - 编辑距离/最长文本长度)
-
加权融合:将两种相似度按照设定权重(默认0.7和0.3)进行加权计算
3. 关键函数流程图
主计算流程如下:
余弦相似度计算流程:
4. 算法独到之处
- 结合两种相似度算法的优势,既考虑词频分布特征,又考虑字符级别的编辑差异
- 针对长文本进行停用词过滤,提高计算效率和准确性
- 预处理阶段对特殊符号和标点进行统一处理,减少干扰因素
- 支持中英文混合文本的处理,适应性更强
三、计算模块接口部分的性能改进
1. 性能改进过程
在完成初始版本后,使用JProfiler进行性能分析,发现以下性能瓶颈:
- 分词操作在处理长文本时耗时较长
- 余弦相似度计算中向量构建过程存在冗余操作
- 预处理阶段字符串替换操作效率不高
针对以上问题,采取了以下改进措施:
- 优化分词流程,减少不必要的对象创建
- 改用更高效的词频统计数据结构(HashMap -> ArrayMap)
- 合并预处理阶段的正则替换操作,减少字符串对象创建
- 对长文本采用分批处理策略,降低内存占用
性能优化花费时间约90分钟。
2. 性能分析图
优化后,程序的主要性能消耗集中在:
TextProcessor.segmentText()
:分词操作,约占总耗时的45%SimilarityCalculator.calculateCosineSimilarity()
:余弦相似度计算,约占总耗时的30%
四、计算模块部分单元测试展示
1. 部分单元测试代码
// 测试1: 学术文本余弦相似度(部分重复)
@Test
public void testCosineSimilarityAcademicPartial() {
List<String> words1 = Arrays.asList("人工智能", "是", "研究", "如何", "使计算机", "模拟", "人类", "智能", "活动", "的", "科学");
List<String> words2 = Arrays.asList("人工智能", "研究", "计算机", "如何", "实现", "类似", "人类", "的", "智能", "行为");
double similarity = calculator.calculateCosineSimilarity(words1, words2);
assertEquals(0.577, similarity, 0.001);
}
// 测试4: 轻度修改的论文段落(同义词替换)
@Test
public void testEditDistanceMildModification() {
String text1 = "计算机视觉是人工智能的一个重要分支,它使计算机能够从图像或视频中获取高级理解。";
String text2 = "机器视觉作为人工智能的关键领域,让计算机可以从图像和视频中获得高层级认知。";
double similarity = calculator.calculateEditDistanceSimilarity(text1, text2);
assertEquals(0.714, similarity, 0.001);
}
// 测试10: 包含特殊符号的文本
@Test
public void testTextWithSpecialSymbols() {
String text1 = "算法复杂度分析中,O(n log n) 通常优于 O(n²),尤其是当 n 很大时。";
String text2 = "在算法复杂度分析里 O n log n 一般比 O n² 更好 特别是当 n 很大的时候";
double similarity = calculator.calculateSimilarity(text1, text2, 0.5, 0.5);
assertEquals(0.833, similarity, 0.001);
}
2. 测试思路说明
测试用例设计主要考虑以下场景:
- 完全相同的文本
- 部分重复的学术文本
- 不同领域的文本
- 轻度修改(同义词替换)的文本
- 结构调整的文本
- 大幅修改但保留核心意思的文本
- 包含特殊符号的文本
- 极短文本
- 中英文混合文本
- 空文本或异常输入
通过覆盖这些场景,确保程序在各种情况下都能正确计算相似度。
3. 测试覆盖率
目前对主要的类(SimilarityCalculator
)单元测试覆盖率达到100%,覆盖了所有核心计算逻辑和异常处理路径。
五、计算模块部分异常处理说明
本程序设计了多种异常处理机制,确保程序的健壮性:
-
空文本异常
- 设计目标:当输入文本为空时,提示用户无法进行查重
- 测试用例:
@Test(expected = IllegalArgumentException.class) public void testEmptyText() { calculator.calculateSimilarity("", "有效文本", 0.5, 0.5); }
- 错误场景:用户输入空文件或仅包含空白字符的文件
-
文件不存在异常
- 设计目标:当指定路径的文件不存在时,给出明确提示
- 测试用例:
@Test(expected = FileNotFoundException.class) public void testFileNotFound() throws IOException { FileHandler.readFile("nonexistent.txt"); }
- 错误场景:用户输入错误的文件路径或文件名
-
空指针异常
- 设计目标:防止输入null值导致程序崩溃
- 测试用例:
@Test(expected = IllegalArgumentException.class) public void testNullInput() { calculator.calculateSimilarity(null, "文本", 0.5, 0.5); }
- 错误场景:外部调用时传入null参数
-
参数非法异常
- 设计目标:确保权重参数在有效范围内
- 测试用例:
@Test(expected = IllegalArgumentException.class) public void testInvalidWeight() { calculator.calculateSimilarity("文本1", "文本2", 1.5, -0.3); }
- 错误场景:权重参数超出[0,1]范围
附录:程序使用说明
- 编译程序生成JAR包:
main.jar
- 命令行运行:
java -jar main.jar [原文文件路径] [抄袭版论文路径] [结果输出路径]
- 示例:
java -jar main.jar C:\examples\orig.txt C:\examples\orig_add.txt C:\ans\ans.txt
- 输出结果为浮点型,精确到小数点后两位
程序支持处理中英文混合文本,能够有效识别各种形式的文本修改,计算结果准确可靠。