PHP四种相似度检测方案+改进计算字符串相似度的函数similar_text()、levenshtein()

  • 发表于
  • PHP

需求

题库系统中对题目进行重复度检测,把所有重复的题目展示出来。

如何定义重复?

刚开始是按100%重复,才算重复。
现要求,70%的重复,也算重复。

分析

背景知识:题目=题干+选项
1.100%重复的情况下,只需要,获取题干数组,php获取重复的项,再获取对应的文章id就好了。
2.php如何获取数组中,70%重复的题目id呢?

PHP相似度重复检测函数,网上一般有四种方法

I similar_text()

php内置函数,具体使用方法,请百度,对中文字符串支持不好

II levenshtein()

php内置函数,具体方法,百度
这个好像更快,但是对字符串长度有限制,超过255,就无法检测。报错信息如下:

III 自定义php检测类,不考虑性能,无字符限制,但是中文检测不准

IV 改进型

PHP改进计算字符串相似度的函数similar_text()、levenshtein()

最终选用四的方法中,对leveshtein的改进

优势:1.计算准确 2.打破255的长度限制

如何获取题干中,70%重复的元素呢

s数据量巨大的时候,有什么高效的算法吗

有人跟我遇到了同样的问题-----数据两两比较的高效算法?
好像这里也没人解决掉了,但是需求是一样的。

百度到了js的算法,改了改,就得到了php数组的两两比较算法

https://www.cnblogs.com/cn-oldboy/p/13580690.html

继续有新的问题,题目众多,比如10W条数据

即便是倒三角算法,还是有着很庞大的计算量。

最终得到相似度检测重复度的方案

1.使用改进版的levenshtein_cn()函数
2.分块检测,不同栏目重复度为0
3.分长度检测,元素的长度如果相差20个字符。直接判断重复度为0
4.分题型检测,不用题型,重复度为0
5.使用倒三角,减少对比次数
6.为了获取丰富的文章信息,以便限制对比次数,推荐使用
获取单列或多列字段值:column( )
参考地址:https://www.php.cn/php/php-column-method.html

关于分块检测又思考如下:thinkphp5能不能在循环中,使用db类?

两种方法

1.我们是一次获取所有题干,并带上栏目信息
2.循环所有栏目,在栏目内部,使用db类,获取题干数组,进行对比
听人说,不建议在循环中使用db,多次操作数据库,会增加服务器开销。
那就使用第一种方法吧

继续操作,如何从数据库一次性获取所有文章,然后根据不同的栏目,生成新的数组

答案:过滤+闭包=====https://www.cnblogs.com/cn-oldboy/p/13583868.html

via

PHP小技巧之计算文本相似度

PHP计算查找多个字符串最长公共前缀