以KMP为核心的带去干扰、语句切割的细颗粒度文本查重算法

核心算法思想:

KMP算法

有如下两个字符串

String str1="1234561237802";//被检测字符串

String str1="121234161137102";//提供对比的字符串

利用KMP算法可找出最长公共子串为s="1234",则相似度float rate=(float)s.length/(float)str1.length=4/11=0.36363636

则我们可认为被检测字符串与对比字符串的相似度为36.36%

对于带语义的多行文本进行检测的时候,不能直接将两文本求公共子串,这样的相似度效率是非常低的,尤其是在网页富文本编辑框写出的文本中,带有网页标签。

需要进行

全文本除杂->语句分割->语句除杂

语义分析

将多行文本拆分成句子,对每句话进行查重

利用分号;句号。逗号,换行符\n等具有分隔句子意义的字符进行文本分割

第一步:全文本除杂

一.1去除 //这个网页中空格的转义字符串会对接下来以;进行语句分割造成严重干扰,提前除杂

第二步:网页层面语句分割和除杂

二.1以网页换行标签<br>进行语句分割成多个语句

二.2以正则表达式去除所有网页标签

private static String cleanHtmlTag(String src)
    {
        return src.replaceAll("<\\/?.+?\\/?>","");
    }
 

第三步:语义层面语句分割和除杂

三.1以"[;!,。;:]"进行语句分割

三.2以"[^a-zA-Z0-9\\u4e00-\\u9fa5]"进行除杂,去除非数字字母汉字部分

第四步:使用KMP算法对被检测文本进行语句级别查重

被检测字符串语句数组a1[]

提供对比字符串语句数组a2[]

伪代码:

float DuplicationRate=0.0f;//整个文本的相似度

for(s1:a1)

    {

    float maxDuplicationRate=0.0f;//某一行文本的相似度

       for(s2:a2)

           {

            float tempRate=detect(s1,s2);//detect方法检测这两个语句的相似度

            if(tempRate>maxDuplicationRate)

                maxDuplicationRate=tempRate;

            if(maxDuplicationRate==1.0)

                break;

           }

        DuplicationRate+=maxDuplicationRate;

    }

DuplicationRate/=s1.length;

detect方法如下:

伪代码:

 float detect(String s1,String s2)

{

    1.kmp算法求出公共子串

     2.相似度等于公共子串长度除以被检测字符串长度()

}

获得被检测文本单个语句和对比文本中语句的公共子字符串,限制子字符串长度必须大于阈值5才计算相似度比率

posted @ 2020-01-12 03:04  HumorChen99  阅读(1)  评论(0编辑  收藏  举报  来源