论文查重算法

Github:https://github.com/ywx1207/ywx1207

这个作业属于哪个课程 工程概论
作业要求在哪里 https://edu.cnblogs.com/campus/jmu/ComputerScience21/homework/13034
作业目标 Github项目管理,熟悉项目开发过程

作业需求

题目:论文查重

描述如下:

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

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

从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位

PSP表格

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

开发环境

语言:java 14
工具:IDEA 2020
系统:Windows 11

算法设计

算法思路

1.读入两篇文章并转化为字符串
2.使用正则表达式匹配并去除文章标点符号
3.使用中文分词库HanLP进行文本分词
4.使用余弦相似度算法统计词频并计算出相似度
5.将结果写入目标文件

函数

函数 作用
calculateSimHash 计算SimHash值
calculateHammingDistance 计算海明距离
hash 哈希函数
readTextFromFile 从txt文件中读取内容

流程图

性能分析

单元测试



异常处理

读取文件可能会出现IO异常

结果

点击查看代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;

public class PlagiarismChecker {

    private static final int HASH_SIZE = 64; // SimHash的哈希位数
    private static final int SIMILARITY_THRESHOLD = 10; // 相似度阈值

    // 计算SimHash值
    private static long calculateSimHash(String text) {
        int[] hashBits = new int[HASH_SIZE];

        // 分词处理
        String[] words = text.split("\\s+");

        // 生成哈希值
        for (String word : words) {
            long wordHash = hash(word);
            for (int i = 0; i < HASH_SIZE; i++) {
                long bitmask = 1L << i;
                if ((wordHash & bitmask) != 0) {
                    hashBits[i] += 1;
                } else {
                    hashBits[i] -= 1;
                }
            }
        }

        // 构造SimHash值
        long simHash = 0;
        for (int i = 0; i < HASH_SIZE; i++) {
            if (hashBits[i] >= 0) {
                simHash |= 1L << i;
            }
        }

        return simHash;
    }

    // 计算海明距离
    private static int calculateHammingDistance(long hash1, long hash2) {
        long xor = hash1 ^ hash2;
        int distance = 0;
        while (xor != 0) {
            distance += 1;
            xor &= xor - 1;
        }
        return distance;
    }

    // 哈希函数
    private static long hash(String word) {
        // 在实际应用中,可以使用更复杂的哈希函数
        return word.hashCode();
    }

    // 从txt文件中读取内容
    private static String readTextFromFile(String filePath) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String file1 = "E:\\JavaProject\\untitled2\\orig.txt";
        String file2 = "E:\\\\JavaProject\\\\untitled2\\\\orig_add.txt";
        String answerFile = "E:\\\\JavaProject\\\\untitled2\\\\answer.txt";

        try {
            // 从文件中读取论文内容
            String paper1 = readTextFromFile(file1);
            String paper2 = readTextFromFile(file2);

            // 计算SimHash值
            long hash1 = calculateSimHash(paper1);
            long hash2 = calculateSimHash(paper2);

            // 计算海明距离
            int distance = calculateHammingDistance(hash1, hash2);

            // 计算重复率
            double similarity = 1.0 - (double) distance / HASH_SIZE;

            // 折算成百分制并保留小数点后两位
            double similarityPercentage = similarity * 100;
            DecimalFormat decimalFormat = new DecimalFormat("0.00");
            String formattedSimilarity = decimalFormat.format(similarityPercentage);

            // 输出结果到答案文件
            try (PrintWriter writer = new PrintWriter(new FileWriter(answerFile))) {
                writer.println("Paper 1: " + paper1);
                writer.println("Paper 2: " + paper2);
                writer.println("相似度: " + formattedSimilarity + "%");

            }
            System.out.println("Plagiarism check completed. Results written to " + answerFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

总结

论文查重算法是用于检测和比较文本相似性的工具,它在学术界和出版领域中扮演着重要的角色。以下是对论文查重算法的总结经验:

基于文本相似性的算法:论文查重算法主要通过比较文本之间的相似性来判断是否存在抄袭或重复内容。常用的算法包括字符串匹配算法(如KMP算法、BM算法)、编辑距离算法(如Levenshtein距离)、向量空间模型(如TF-IDF、余弦相似度)以及基于机器学习的方法(如文本分类、词嵌入)等。

效果与速度的权衡:不同的算法在查重效果和速度上存在权衡。一些算法可能在查重准确性方面表现较好,但耗时较长;而另一些算法可能速度更快,但查重结果相对粗略。具体选择算法时需要根据需求权衡各方面因素。

多重算法组合:为了提高查重效果,可以采用多重算法组合的方式。例如,可以先使用快速的字符串匹配算法进行初步筛查,再利用向量空间模型或机器学习方法进行进一步比对。多重算法组合可以综合各个算法的优势,提高查重的准确性和效率。

数据库规模和覆盖度:论文查重算法的效果还与所使用的数据库规模和覆盖度有关。更大规模的数据库可以提供更全面的比对参考,从而提高查重的准确性。因此,在选择查重算法时,需要考虑数据库的规模和覆盖度,并确保所使用的数据库与研究领域或文本类型相匹配。

定期更新算法和数据库:由于学术界和出版领域的发展,新的论文查重算法和数据库不断涌现。为了保持查重效果的准确性和时效性,建议定期更新算法和数据库,以跟上最新的研究进展和文献积累。

结合人工审查:尽管论文查重算法可以自动检测文本相似性,但最终的判断还需要结合人工审查。算法结果只是提供参考,人工审查可以进一步判断是否存在抄袭或重复内容,并给出合适的评估和处理。

总之,论文查重算法是一个复杂而且不断发展的领域,需要综合考虑多种算法和数据库的特点。通过合理选择和组合算法,并结合人工审查,可以有效地检测和处理抄袭问题,维护学术诚信和研究质量。

posted @   海星-yx  阅读(131)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示