个人项目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023/
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023/homework/13324

GitHub链接:https://github.com/lzw0312/lzw0312/tree/master

一.PSP表格

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

二.计算模块接口的设计与实现

1.项目结构

2.主函数流程图

3.PlagiarismChecker流程图

4.算法关键:文本预处理、分词、余弦相似度

5.独到之处:通过文本预处理方法,能够去除标点符号、特殊字符和多余空格的影响,确保分词和相似度计算的准确性。利用LanLP工具将文本分割成单词或词组,最后通过计算余弦相似度得出重复率

三.性能分析图


由性能分析图可知public static Set tokenize(String text) 对文本进行分词这个函数消耗最大,后续应该优化分词功能,可以通过异步操作减少时间消耗,或采用更高级的算法

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

1.测试代码

点击查看代码
private static final String ANSWER_TEST_FILE = "C:\\Users\\Aurora\\Desktop\\answer.txt";

    /**
     * 测试完全相同的文本
     * 预期结果:相似度应为1.0
     */
    @Test
    public void testIdenticalText() {
        String result = PlagiarismChecker.plagiarismChecker("今天是星期天,天气晴,今天晚上我要去看电影。", "今天是星期天,天气晴,今天晚上我要去看电影。", ANSWER_TEST_FILE);
        assertTrue("测试完全相同文本,结果因为1.00", Double.parseDouble(result) == 1.00);

    }

    /**
     * 测试未抄袭文本
     * 预期结果:结果应小于0.3
     */
    @Test
    public void testWithoutPlagiarizingText() {

        String result = PlagiarismChecker.plagiarismChecker("今天是星期天,天气晴,今天晚上我要去看电影。", "我明天要和你一起吃饭", ANSWER_TEST_FILE);
        assertTrue("测试未抄袭文本,结果应小于0.3", Double.parseDouble(result) < 0.5);
    }

    /**
     * 测试原文本为空
     * 预期结果:返回“”
     */
    @Test
    public void testEmptyOrignalText() {

        String result = PlagiarismChecker.plagiarismChecker("", "我明天要和你一起吃饭", ANSWER_TEST_FILE);
        assertTrue("测试原文本为空,结果应为空字符", result.equals(""));
    }

    /**
     * 测试抄袭文本为空
     * 预期结果:返回“”
     */
    @Test
    public void testEmptyCopiedText() {

        String result = PlagiarismChecker.plagiarismChecker("今天是星期天,天气晴,今天晚上我要去看电影。", "", ANSWER_TEST_FILE);
        assertTrue("测试抄袭文本为空,结果应为空字符", result.equals(""));
    }

    /**
     * 测试原文本和抄袭文本都为空
     * 预期结果:返回“”
     */
    @Test
    public void testTextBothEmpty() {
        String result = PlagiarismChecker.plagiarismChecker("", "", ANSWER_TEST_FILE);
        assertTrue("测试原文本和抄袭文本都为空,结果应为空字符", result.equals(""));

    }

    /**
     * 测试特殊符号
     * 预期结果:特殊符号不影响结果,结果应为0.00
     */
    @Test
    public void testSpecialSymbol() {
        String result = PlagiarismChecker.plagiarismChecker(",.!英语", ",.!语文", ANSWER_TEST_FILE);
        assertTrue("测试原文本和抄袭文本都为空,结果应为空字符", Double.parseDouble(result) == 0.00);

    }

    /**
     * 测试包含数字的文本
     * 预期结果:数字不影响结果
     */
    @Test
    public void testNumbers() {
        String result = PlagiarismChecker.plagiarismChecker("今天是2023年10月1日", "今天是 2023 年 10 月 1 日", ANSWER_TEST_FILE);
        Assert.assertTrue("测试数字,结果应为1.0", Double.parseDouble(result) == 1.0);
    }

    /**
     * 测试短抄袭文本
     * 预期结果:结果应大于0.8
     */
    @Test
    public void testPlagiarizingText() {
        String result = PlagiarismChecker.plagiarismChecker("今天是星期天,天气晴,今天晚上我要去看电影。", "今天是周天,天气晴朗,我晚上要去看电影。", ANSWER_TEST_FILE);
        assertTrue("测试未抄袭文本,结果应大于0.8", Double.parseDouble(result) > 0.80);
    }

    /**
     * 测试长抄袭文本
     * 预期结果:结果应大于0.5
     */
    @Test
    public void testLongPlagiarizingText() throws InterruptedException {
        String result = PlagiarismChecker.plagiarismChecker("今天是星期天,天气晴朗,我和家人一起去了公园。公园里有很多人,有的在跑步,有的在打羽毛球,还有的在放风筝。我们找了一个安静的地方坐下,享受着阳光和微风。孩子们在草地上嬉戏玩耍,笑声不断。中午我们在公园里的餐厅吃了午饭,饭后继续散步,直到傍晚才回家。这一天过得非常愉快,希望下次还能来",
                "今天是周日,天气非常好,我和家人一起去逛公园。公园里聚集了不少人,有人在慢跑,有人在打羽毛球,还有人在放风筝。我们选择了一处宁静的地方休息,尽情享受阳光与轻柔的微风。孩子们在草坪上欢快地奔跑,充满了欢声笑语。中午时分,我们在公园内的餐馆享用了午餐,之后又漫步了一会儿,直到傍晚才离开。这真是美好的一天,期待下次再来",
                ANSWER_TEST_FILE);
        assertTrue("测试未抄袭文本,结果应大于0.8", Double.parseDouble(result) >= 0.50);

    }

    /**
     * 测试文本长度差异较大
     * 预期结果:算法应能正确处理长度差异较大的文本
     */
    @Test
    public void testLengthDifference() {
        String result = PlagiarismChecker.plagiarismChecker("今天是星期天,天气晴,今天晚上我要去看电影。",
                "今天是周日,天气非常好,我和家人一起去逛公园。公园里聚集了不少人,有人在慢跑,有人在打羽毛球,还有人在放风筝。我们选择了一处宁静的地方休息,尽情享受阳光与轻柔的微风。孩子们在草坪上欢快地奔跑,充满了欢声笑语。中午时分,我们在公园内的餐馆享用了午餐,之后又漫步了一会儿,直到傍晚才离开。这真是美好的一天,期待下次再来",
                ANSWER_TEST_FILE);
        assertTrue("测试未抄袭文本,结果应小于于0.5", Double.parseDouble(result) <= 0.50);
    }

2.测试覆盖率截图

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

1.异常代码

点击查看代码
public class ExceptionTest {

    /**
     * 测试输入文件数目的异常情况
     */
    @Test
    public void main_InvalidNumberOfArguments_ShouldPrintErrorMessage()  {
        String[] args = {"file1.txt", "file2.txt"};
        System.setOut(new java.io.PrintStream(new java.io.ByteArrayOutputStream()));
        assertThrows(IllegalArgumentException.class, () -> {
            Main.main(args);
        });
    }

    /**
     * 测试读入文件的异常情况
     */
    @Test
    public void FileUtil_readFile_ShouldPrintErrorMessage() {
        System.setOut(new java.io.PrintStream(new java.io.ByteArrayOutputStream()));
        assertThrows(FileNotFoundException.class, () -> {
            FileUtil.readFile("file1.txt");
        });
    }


    /**
     * 测试写入文件的异常情况
     */
    @Test
    public void FileUtil_writeFile_ShouldPrintErrorMessage() {
        String[] args = {"C:\\Users\\Aurora\\Desktop\\orig.txt",
                "C:\\Users\\Aurora\\Desktop\\orig_0.8_add.txt" ,
               "file2.txt"};
        System.setOut(new java.io.PrintStream(new java.io.ByteArrayOutputStream()));
        assertThrows(FileNotFoundException.class, () -> {
            Main.main(args);
        });
    }
}

2.设计目标
2.1 IllegalArgumentException:输入参数个数不正确时抛出
2.2 FileNotFoundException:当文件不存在时抛出
2.3 RuntimeException:IO操作出错时抛出

posted @ 2025-03-08 21:11  baea  阅读(38)  评论(0)    收藏  举报