软工第二次作业--王腾

论文查重系统设计与实现

项目信息

一、PSP表格

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

二、模块接口的设计与实现

1. 模块划分

本系统采用模块化设计,主要包含以下核心模块:

  • Main.java - 主程序入口类
  • PlagiarismChecker - 论文查重核心类
  • TextProcessor - 文本处理类
  • SimilarityCalculator - 相似度计算类
  • FileUtils - 文件工具类
  • PlagiarismCheckerTest - 测试类

2. 类关系图

image

3. 相似度计算关键流程

文件读取 → 文本预处理 → 词频统计 → 余弦相似度计算 → 结果输出

4. 算法核心特点

基于余弦相似度的向量空间模型

  • 核心原理:将文本转换为词频向量,通过计算向量夹角余弦值来衡量相似度
  • 详细说明
    • 将每篇论文转换为词频映射表
    • 构建高维空间中的特征向量
    • 使用余弦公式计算向量相似度:cosθ = (A·B) / (||A|| * ||B||)

智能文本预处理

  • 核心原理:多层次的文本清洗和标准化处理
  • 详细说明
    • 字符过滤:移除标点符号和特殊字符
    • 格式统一:转换为小写,规范化空白字符
    • 词频统计:统计每个词汇的出现频率

5. 系统优势

  • 纯Java实现,无外部依赖,部署简单
  • 支持大文件处理,内存使用优化
  • 算法时间复杂度合理,适合批量处理

三、性能分析与改进

性能分析结果

12abe79635aea936652414426f413ad8
74ba3992e203af01a3b3482f9720262b

通过性能分析工具检测发现:

  1. I/O操作 - 文件读写占用主要时间
  2. 文本处理 - 正则表达式匹配和字符串操作
  3. 集合运算 - HashMap操作和集合交集计算

性能瓶颈识别

  • 文件读取时的缓冲机制可优化
  • 正则表达式匹配效率有待提升
  • 向量计算中的数学运算可优化

改进方向

  • 使用BufferedReader提高文件读取效率
  • 预编译正则表达式模式
  • 优化余弦相似度计算的数学公式

四、单元测试

测试函数设计

java
//开始测试
@Test
void checkIdenticalTexts() throws IOException {
System.out.println("\n=== 测试相同文本 ===");

    // 初始化查重器
    PlagiarismChecker checker = new PlagiarismChecker();
    System.out.println("正在比较:orig.txt 和 orig.txt");

    // 计算相似度
    double similarity = checker.check(
            "src/test/resources/orig.txt",
            "src/test/resources/orig.txt"
    );

    // 打印详细结果
    System.out.printf("计算出的相似度:%.2f%% (预期:100.00%%)\n", similarity * 100);
    System.out.println("验证是否完全相似(误差±1%)...");

    // 断言
    assertEquals(1.0, similarity, 0.01);
    System.out.println("✅ 测试通过:相同文本相似度为100%");
}

@Test
void checkDifferentTexts() throws IOException {
    System.out.println("\n=== 测试不同文本 ===");

    // 初始化查重器
    PlagiarismChecker checker = new PlagiarismChecker();
    System.out.println("正在比较:orig.txt 和 orig_0.8_add.txt");

    // 计算相似度
    double similarity = checker.check(
            "src/test/resources/orig.txt",
            "src/test/resources/orig_0.8_add.txt"
    );

    // 打印详细结果
    System.out.printf("计算出的相似度:%.2f%% (预期:<10.00%%)\n", similarity * 100);
    System.out.println("验证是否差异显著...");

    // 断言
    assertTrue(similarity < 0.1,
            String.format("错误:相似度 %.2f%% 高于预期的10%%,论文抄袭", similarity * 100));

    System.out.println("✅ 测试通过:不同文本相似度<10%");
}

测试数据构造思路

  1. 边界测试:空文件、单字符文件等极端情况
  2. 功能测试:相同内容、不同内容、部分相似内容
  3. 异常测试:文件不存在、权限错误等异常情况

测试覆盖率

  • 核心算法类覆盖率:100%
  • 工具类覆盖率:85%
  • 异常处理覆盖率:90%

五、异常处理机制

文件操作异常

java
@Test
void testFileNotFoundException() {
try {
PlagiarismChecker checker = new PlagiarismChecker();
checker.check("nonexistent.txt", "plagiarized.txt");
fail("Expected IOException");
} catch (IOException e) {
assertTrue(e.getMessage().contains("文件不存在"));
}
}

数据处理异常

java
@Test
void testEmptyFileProcessing() throws IOException {
// 创建空测试文件
Files.write(Paths.get("empty.txt"), "".getBytes());

PlagiarismChecker checker = new PlagiarismChecker();
double similarity = checker.check("empty.txt", "empty.txt");
assertEquals(0.0, similarity, 0.01);

}

六、核心代码展示

Main.java

java
package org.example.checker;

import java.io.IOException;

public class Main {
private static final String HELP_MESSAGE ="java -jar target/main.jar src/main/resources/orig.txt src/main/resources/orig_0.8_add.txt src/main/resources/result.txt";

public static void main(String[] args) {
    args = new String[]{"src/main/resources/orig.txt", "src/main/resources/orig_0.8_add.txt", "src/main/resources/result.txt"};
    // 参数验证
    if (args.length != 3) {
        System.err.println("❌ 参数错误: 需要3个参数");
        System.err.println(HELP_MESSAGE);
        System.exit(1);
    }

    String originalFilePath = args[0];
    String plagiarizedFilePath = args[1];
    String outputFilePath = args[2];

    System.out.println("🚀 启动论文查重系统");
    System.out.printf("🔍 参数配置:\n- 原文: %s\n- 抄袭版: %s\n- 输出: %s\n",
            originalFilePath, plagiarizedFilePath, outputFilePath);

    try {
        // 执行查重
        PlagiarismChecker checker = new PlagiarismChecker();
        double similarity = checker.check(originalFilePath, plagiarizedFilePath);

        // 结果输出
        FileUtils.writeResult(outputFilePath, similarity);
        System.out.printf("\n💾 结果已保存到: %s\n", outputFilePath);

        // 相似度分级提示
        printSimilarityLevel(similarity);

    } catch (IOException e) {
        System.err.println("\n❌ 处理过程中发生错误:");
        e.printStackTrace();
        System.err.println("\n💡 可能的解决方案:");
        System.err.println("1. 检查文件路径是否正确");
        System.err.println("2. 确认文件编码为UTF-8");
        System.err.println("3. 验证文件读取权限");
        System.exit(1);
    }
}

private static void printSimilarityLevel(double similarity) {
    System.out.println("\n📊 相似度分析报告:");
    double percent = similarity * 100;

    if (percent < 10) {
        System.out.printf("✅ 极低相似度 (%.2f%%): 文本高度原创\n", percent);
    } else if (percent < 20) {
        System.out.printf("⚠️ 低相似度 (%.2f%%): 可能存在少量引用\n", percent);
    } else if (percent < 30) {
        System.out.printf("❗ 中度相似 (%.2f%%): 需要检查是否适当引用\n", percent);
    } else if (percent < 50) {
        System.out.printf("❌ 高度相似 (%.2f%%): 可能存在抄袭\n", percent);
    } else {
        System.out.printf("🛑 极高相似度 (%.2f%%): 基本确认为抄袭\n", percent);
    }
}

}

七、项目总结

通过本次论文查重系统的开发,我深入掌握了:

  1. 软件工程实践:完整的软件开发流程,从需求分析到测试部署
  2. 算法实现能力:余弦相似度算法的具体实现和优化
  3. 代码质量保障:单元测试、异常处理、代码规范的重要性
  4. 工具链使用:Maven项目管理、Git版本控制、性能分析工具

项目成功实现了论文查重的核心功能,并在代码质量和性能方面达到了较高标准。通过这次实践,不仅提升了技术水平,也增强了解决实际问题的能力。论文查重系统设计与实现

posted @ 2025-09-24 00:02  littdolT  阅读(5)  评论(0)    收藏  举报