minhash算法检索相似文本_程序员自然语言处理编程算法,解决文本相似度问题的最长公共子串...

本文探讨了文本相似度问题,介绍了基于最长公共子串的算法,包括暴力解法、动态规划法和后缀数组法。这些方法用于文本去重、搜索引擎判重等领域。动态规划法的时间复杂度为O(mn),后缀数组法进一步降低了时间复杂度。后续将讲解更多字符串相似度计算算法。
摘要由CSDN通过智能技术生成

从本文开始要讲一个非常重要的问题:文本相似度问题,通过计算两个文本相似度,以达到文本的判重的目的。它的应用有很多,比如文本去重、搜索引擎网页判重、论文的反抄袭等。

b64a91e96398c0f4937edbef6bd4dc2c.png

解决文本相似度问题的算法有很多,本文就先讲一个比较简单的,基于最长公共子串的算法

如果要比较两篇文档的相似度,可以将两篇文档看出是两个字符串序列,将其统一归一化处理后,可以转化为最长公共子串的问题。那么解决最长公共子串的算法又有很多,下面将逐个讲解。

一. 暴力解法

直接通过两个循环枚举第一个字符串的子串,然后判断其在第二个字符串中是否包含,并记录包含第一个字符串子串的最大长度即可。很明显,这样的解法时间复杂度是大于O(nm)的,代码如下

int LS(string x, string y) { int maxLen = 0; int xlen = x.size(); int ylen = y.size(); for (int i = 0; i < xlen; i++) { int len = 0; string str = ""; for (int j = i; j < ylen; j++) { str += x[j]; if (y.find(str) == y.npos) { break; } len++; } maxLen = max(maxLen, len); } return maxLen;}

这里在判断是否包含子串时用到了STL的find函数,它的平均时间复杂度为O(m+n),但最坏时间复杂度为O(mn),可以将其改为KMP匹配算法,那么整体时间复杂度为O(m*n*(m+n))。这种暴力算法性能太差,那么下面基于动态规划的方法性能又要好很多。

7c0dbb86f55c4cf268794e22ac124eff.png

二. 动态规划法

假如我们用动态规划的思想,对于两个字符串,用dp[i][j]来表示同时以x_i和y_j结尾的子串,那么很明显当x_i不等于y_j时,dp[i][j]=0,当x_i等于y_j时候,dp[i][j] = dp[i - 1][j - 1] + 1,所以转移方程如下

938cc5da1b39b4a68d62d694365c9794.png

那么代码也就很容易了,如下

int LS(string x, string y) { int maxLen = 0; int xlen = x.size(); int ylen = y.size(); for (int i = 0; i <= xlen; i++) { for (int j = 0; j <= ylen; j++) { if (i == 0 || j == 0) { dp[i][j] = 0; } else if (x[i - 1] == y[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = 0; } maxLen = max(maxLen, dp[i][j]); } } return maxLen;}

很明显,动态规划法两个循环,时间复杂度为O(mn),通常这种时间复杂度也就够用了。但其实还有其它更优的算法,例如基于后缀数组的最长公共子串求法。

ff141e04ee79f46621031ad973fafe97.png

三. 后缀数组法

这个算法稍微复杂一点,通过构造后缀数组,时间复杂度会更低。基于二倍增算法的后缀数组时间复杂度为O(n*log(n)),而基于DC3算法的后缀数组时间复杂度为O(n)。后面有时间我会详细讲解这两种算法。

可以看出通过计算公共子串的方法来计算两个串的相似度还存在缺陷,比如很多情况是两个字符串高度相似,但子串并不一定很长,后面我再讲解其它算法来逐步改进这个问题。下一节我会讲解更多关于字符串相似度计算算法,欢迎大家关注!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值