• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

zongyoufengchui

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

软工作业2:个人项目

个人项目

这个作业属于哪个课程 班级链接
这个作业要求在哪里 个人项目要求
这个作业的目标 进行第一次个人项目:学习设计一个论文查重算法

一、Github文件夹链接

github链接

二、作业需求

题目:论文查重

描述如下:

设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。

原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:

从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。

注意:答案文件中输出的答案为浮点型,精确到小数点后两位

三、PSP表格

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

四、设计与思路

开发环境:IntelliJ IDEA Community Edition 2022.2.2
开发语言:JAVA

设计思路

  1. 要实现一个论文查重算法,首先要使用 java.io.BufferedReader 类来读取原版文本以及抄袭版文本的内容,并将其储存在字符串中。
  2. 接着,我们要比较这两个字符串的相似度。方法为:使用 java.util.HashMap 类来存储每个单词及其出现的次数,计算两个字符串中共同拥有的单词数量,并将其除以原文中单词的总数量,最后得到相似度。
  3. 用一个整体的算法来执行整个程序。

算法设计

  1. 使用for循环遍历original字符串(原版文本)中的每个单词,将单词作为键,初始值为 0 的整数作为值,放入wordCount中。如果单词已存在,则累加其值。
  2. 创建一个名为commonWords的整数变量,用于存储两个字符串中共有的单词数量。
  3. 使用for循环遍历copied字符串(抄袭版文本)中的每个单词,检查wordCount中是否包含该单词。
  4. 如果包含该单词,则更新wordCount中该单词的值,减 1,并检查其值是否为 0。如果为 0,则从wordCount中移除该单词。
  5. 如果单词存在于wordCount中,则将commonWords加 1。
  6. 返回commonWords除以original字符串中单词的数量的结果,以 double 类型表示。

流程图

算法概述

本算法仅使用了一个类,但其中已包含了提取文本、处理文本、文本比对三部分,内容基本齐全。
优点:

  1. 算法简单易懂,易于实现。
  2. 时间复杂度较低,对于大规模文本比较,性能较好。
  3. 使用了哈希表存储单词及其出现次数,有效地减少了空间复杂度。

缺点:

  1. 对空格和特殊字符的处理不够灵活,可能会影响结果的准确性。
  2. 算法没有对单词的权重进行处理,可能导致相似度计算不准确。
  3. 算法依赖于单词的出现次数,对于一些罕见的单词,计算结果可能不稳定。

五、模块及完整代码

模块

完整代码

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class PaperCheck {
    public static void main(String[] args) throws IOException {
        String originalFile = "C:\\Users\\56866\\Desktop\\测试文本\\orig.txt";
        String copiedFile = "C:\\Users\\56866\\Desktop\\测试文本\\orig.txt";//可更改为其他文本进行比对
        String answerFile = "C:\\Users\\56866\\Desktop\\测试文本\\result1.txt";//可更改为其他储存名来区分

        String originalContent = readFile(originalFile);
        String copiedContent = readFile(copiedFile);

        double similarity = compareStrings(originalContent, copiedContent);

        writeAnswer(answerFile, similarity);
    }

    private static String readFile(String file) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(file));
        StringBuilder content = new StringBuilder();
        String line;

        while ((line = reader.readLine()) != null) {
            content.append(line).append("\n");
        }

        reader.close();
        return content.toString();
    }

    private static double compareStrings(String original, String copied) {
        if (original == null || copied == null) {
            return 0;
        }

        Map<String, Integer> wordCount = new HashMap<>();

        for (String word : original.split(" ")) {
            wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
        }

        int commonWords = 0;

        for (String word : copied.split(" ")) {
            if (wordCount.containsKey(word)) {
                wordCount.put(word, wordCount.get(word) - 1);
                if (wordCount.get(word) == 0) {
                    wordCount.remove(word);
                }
                commonWords++;
            }
        }

        return (double) commonWords / original.split(" ").length;
    }

    private static void writeAnswer(String file, double similarity) throws IOException {
        if (similarity < 0 || similarity > 1) {
            throw new IllegalArgumentException("相似率应该在0~1之间");
        }

        FileWriter writer = new FileWriter(file);
        writer.write(String.format("%.2f", similarity));
        writer.close();
    }
}

六、测试结果

与自身进行测试


与文件orig_0.8_add.txt进行测试


与文件orig_0.8_dis_1.txt进行测试


与文件orig_0.8_dis_10.txt进行测试


与文件orig_0.8_dis_15.txt进行测试


七、性能分析


八、总结

这是我第一次完成一个个人项目,在这次项目中,我从抓瞎不知道如何下手到静下心来,一步一步地完成,虽然最终的代码并不出色甚至有些过于简单,但这还是耗费了我不少时间,我也学会了很多东西:通过这次经历,我初步地体验到了设计一个程序所经历的各个步骤,第一次使用了jprofiler并学会单元测试和性能分析等。

posted on 2023-09-17 21:46  biemaleyaaa  阅读(55)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3