JAVA 一个简单查重的实现

JAVA 一个简单查重的实现

1. 前言

最近在做一个教育网站时,有一个考试的模块,其中学生编写的文章需要有一个查重的功能。到网上找了下,感觉这方面的资料还是比较少,大部分都需要收费,由于公司家境贫寒(不愿意花钱),且需求不是特别难,只需要一个建议版本的功能。于是只能亲自动手做一个 simple 版本的。

2. 实现思路

思路的话比较简单,想法是利用双指针的模式,找出两个文本中相似的文本。不过这样算法复杂度是 O(n2) ,不过由于我们是小网站,文章本来也不多。

核心就是有一个双层的循环做遍历,然后判断最小字符串是否相同,如果不相同,则指针B递增直到找到相同的文本

如果指针位置找到了相同文本,则增加最小字符串长度,直到找到最大的匹配的文本。

3. 代码实现

java 复制代码
public static class SameResult {
    // 存储相似文本关键词
    private String keyword;
    // 存储与关键词详细信息
    private String detail;

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }
}

/**
 * 获取两个字符串中的相似文本片段
 * @param a 文本a
 * @param b 文本b
 * @param minSize 最小相似字符数
 * @return 返回相似文本片段的列表
 */
public static List<SameResult> getSameTextList(String a, String b, Integer minSize) {

    List<SameResult> result = new ArrayList<>();
    Map<String, String> stash = new HashMap<>();
    if (a == null || b == null) {
        return result;
    }
    if (a.length() < minSize || b.length() < minSize) {
        return result;
    }
    int i = 0;
    while (i <= a.length() - minSize) {
        // 初始化窗口大小为最小相似字符数
        int nowWindowSize = minSize;
        // 遍历文本b,寻找与文本a当前片段相似的片段
        int j = 0;
        String nowMate = null; // 存储当前相似片段
        String nowDetail = null; // 存储当前相似片段的详细信息
        SameResult sameResult = new SameResult(); 
        Boolean isMate = false; // 标记是否找到相似片段
        while (j <= b.length() - minSize) {
            // 如果文本a和文本b的当前片段相等
            if (a.substring(i, nowWindowSize + i).equals(b.substring(j, nowWindowSize + j))) {
                // 记录相似片段
                nowMate = a.substring(i, nowWindowSize + i); 
                // 记录详细信息, 这里的5表示详细信息取前五个和后五个字符
                nowDetail = b.substring(Math.max(j - 5, 0), Math.min(nowWindowSize + j + 5, b.length())); 
                sameResult.setKeyword(nowMate); 
                sameResult.setDetail(nowDetail); 
                // 设置找到相似片段的标记
                isMate = true; 
                // 增加窗口大小
                nowWindowSize++; 
                // 继续在文本b中寻找更长的相似片段
                while (j <= b.length() - nowWindowSize) {
                    String ma1 = a.substring(i, nowWindowSize + i);
                    String ma2 = b.substring(j, nowWindowSize + j);
                    // 如果找到更长的相似片段
                    if (ma1.equals(ma2)) { 
                        nowMate = a.substring(i, nowWindowSize + i); 
                        nowDetail = b.substring(Math.max(j - 5, 0), Math.min(nowWindowSize + j + 5, b.length())); 
                        sameResult.setKeyword(nowMate); 
                        sameResult.setDetail(nowDetail); 
                        nowWindowSize++;
                    } else {
                        // 如果不再相似,退出循环
                        break; 
                    }
                }
                // 找到相似片段后,退出内部循环
                break; 
            } else {
                // 如果不相似,继续在文本b中寻找
                j++; 
            }
        }
        // 如果找到相似片段,将其存储到映射中
        if (isMate) {
            // 移动文本a的索引
            i += nowWindowSize - 1;
            stash.put(sameResult.getKeyword(), sameResult.getDetail()); 
        } else {
            // 如果没有找到相似片段,移动文本a的索引
            i++; 
        }
    }
    for (String key : stash.keySet()) {
        SameResult sameResult = new SameResult();
        sameResult.setKeyword(key);
        sameResult.setDetail(stash.get(key)); 
        result.add(sameResult); 
    }
    return result;
}

public static void main(String[] args) {
    // 调用getSameTextList方法,并打印结果
    System.out.println(getSameTextList("test1", "test2", 10));
}

代码总体比较简单,就是获取到所有最小长度文本长度的所有相似文本,并放到一个 List 中,以便后续的业务处理。

最后可以整理为一个类似下面的表格

原文 相似内容
脸哭声更为响亮。我问他是谁 的悲他把他脸哭声更为响亮。我问他是谁使的打成这
情往往只是作为情 的友爱和险情往往只是作为情可来及,正
着茂盛树叶的树下 节了一棵已着茂盛树叶的树下,走的女棉花
再说我爹年轻时也 我端人的子。再说我爹年轻时也好些一手,

4. 结尾

一般会用到查重的业务场景可能并不多,大部分都是学校、政府等才需要进行查重,本文算是抛砖引玉吧,只是为需要做查重内容展示时为大家提供一点点思路。

相关推荐
小_太_阳1 小时前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
智慧老师1 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
搬码后生仔2 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
凡人的AI工具箱2 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
Lx3523 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas
小池先生3 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
百罹鸟3 小时前
【vue高频面试题—场景篇】:实现一个实时更新的倒计时组件,如何确保倒计时在页面切换时能够正常暂停和恢复?
vue.js·后端·面试
小蜗牛慢慢爬行4 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
wm10435 小时前
java web springboot
java·spring boot·后端
龙少95437 小时前
【深入理解@EnableCaching】
java·后端·spring