PHP中计算字符串相似度的函数代码


Posted in PHP onDecember 29, 2012

similar_text — 计算两个字符串的相似度
int similar_text ( string $first , string $second [, float &$percent ] )
$first 必需。规定要比较的第一个字符串。
$second 必需。规定要比较的第二个字符串。
$percent 可选。规定供存储百分比相似度的变量名。

两个字符串的相似程度计算依据 Oliver [1993] 的描述进行。注意该实现没有使用 Oliver 虚拟码中的堆栈,但是却进行了递归调用,这个做法可能会导致整个过程变慢或变快。也请注意,该算法的复杂度是 O(N**3),N 是最长字符串的长度。

比如我们想找字符串abcdefg和字符串aeg的相似度:

$first = "abcdefg"; 

$second = "aeg"; 

echo similar_text($first, $second);结果输出3.如果想以百分比显示,则可使用它的第三个参数,如下: 

$first = "abcdefg"; 

$second = "aeg"; 

similar_text($first, $second, $percent); 

echo $percent;

similar_text函数的使用及实现过程。similar_text() 函数主要是用来计算两个字符串的匹配字符的数目,也可以计算两个字符串的相似度(以百分比计)。与 similar_text() 函数相比,我们今天要介绍的 levenshtein() 函数更快。不过,similar_text() 函数能通过更少的必需修改次数提供更精确的结果。在追求速度而少精确度,并且字符串长度有限时可以考虑使用 levenshtein() 函数。

使用说明

先看手册上 levenshtein() 函数的说明:

levenshtein() 函数返回两个字符串之间的 Levenshtein 距离。

Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

例如把 kitten 转换为 sitting:

sitten (k→s)
sittin (e→i)
sitting (→g)levenshtein() 函数给每个操作(替换、插入和删除)相同的权重。不过,您可以通过设置可选的 insert、replace、delete 参数,来定义每个操作的代价。

语法:

levenshtein(string1,string2,insert,replace,delete)

参数 描述

•string1 必需。要对比的第一个字符串。
•string2 必需。要对比的第二个字符串。
•insert 可选。插入一个字符的代价。默认是 1。
•replace 可选。替换一个字符的代价。默认是 1。
•delete 可选。删除一个字符的代价。默认是 1。
提示和注释

•如果其中一个字符串超过 255 个字符,levenshtein() 函数返回 -1。
•levenshtein() 函数对大小写不敏感。
•levenshtein() 函数比 similar_text() 函数更快。不过,similar_text() 函数提供需要更少修改的更精确的结果。
例子

<?php 

echo levenshtein("Hello World","ello World"); 

echo "<br />"; 

echo levenshtein("Hello World","ello World",10,20,30); 

?>

输出: 1 30

以下是补充:

php默认有个函数similar_text()用于计算字符串之间的相似度,该函数也可以计算两个字符串的相似度(以百分比计)。不过这个函数感觉对中文计算很不准确比如:

echo similar_text("吉林禽业公司火灾已致112人遇难","吉林宝源丰禽业公司火灾已致112人遇难");

这两个新闻标题其实都是一样的,如果使用similar_text()相似对结果为:42,即只相似42%,所以这个感觉很不靠谱,今天刚好收集到一段PHP代码也是用于比较两个字符串的相似度,直接贴出代码:

<?php 
class LCS {
  var $str1;
  var $str2;
  var $c = array();
  /*返回串一和串二的最长公共子序列
*/
  function getLCS($str1, $str2, $len1 = 0, $len2 = 0) {
    $this->str1 = $str1;
    $this->str2 = $str2;
    if ($len1 == 0) $len1 = strlen($str1);
    if ($len2 == 0) $len2 = strlen($str2);
    $this->initC($len1, $len2);
    return $this->printLCS($this->c, $len1 - 1, $len2 - 1);
  }
  /*返回两个串的相似度
*/
  function getSimilar($str1, $str2) {
    $len1 = strlen($str1);
    $len2 = strlen($str2);
    $len = strlen($this->getLCS($str1, $str2, $len1, $len2));
    return $len * 2 / ($len1 + $len2);
  }
  function initC($len1, $len2) {
    for ($i = 0; $i < $len1; $i++) $this->c[$i][0] = 0;
    for ($j = 0; $j < $len2; $j++) $this->c[0][$j] = 0;
    for ($i = 1; $i < $len1; $i++) {
      for ($j = 1; $j < $len2; $j++) {
        if ($this->str1[$i] == $this->str2[$j]) {
          $this->c[$i][$j] = $this->c[$i - 1][$j - 1] + 1;
        } else if ($this->c[$i - 1][$j] >= $this->c[$i][$j - 1]) {
          $this->c[$i][$j] = $this->c[$i - 1][$j];
        } else {
          $this->c[$i][$j] = $this->c[$i][$j - 1];
        }
      }
    }
  }
  function printLCS($c, $i, $j) {
    if ($i == 0 || $j == 0) {
      if ($this->str1[$i] == $this->str2[$j]) return $this->str2[$j];
      else return "";
    }
    if ($this->str1[$i] == $this->str2[$j]) {
      return $this->printLCS($this->c, $i - 1, $j - 1).$this->str2[$j];
    } else if ($this->c[$i - 1][$j] >= $this->c[$i][$j - 1]) {
      return $this->printLCS($this->c, $i - 1, $j);
    } else {
      return $this->printLCS($this->c, $i, $j - 1);
    }
  }
} 

$lcs = new LCS();
//返回最长公共子序列
$lcs->getLCS("hello word","hello china");
//返回相似度
echo $lcs->getSimilar("吉林禽业公司火灾已致112人遇难","吉林宝源丰禽业公司火灾已致112人遇难");

同样输出结果为:0.90322580645161,明显准确的多。

PHP 相关文章推荐
Smarty模板快速入门
Jan 04 PHP
PHP 字符串正则替换函数preg_replace使用说明
Jul 15 PHP
PHP中文分词的简单实现代码分享
Jul 17 PHP
PHP json_decode函数详细解析
Feb 17 PHP
php单例模式示例分享
Feb 12 PHP
表单提交错误后返回内容消失问题的解决方法(PHP网站)
Oct 20 PHP
PHP模板引擎Smarty中变量的使用方法示例
Apr 11 PHP
PHP session 会话处理函数
Jun 06 PHP
PHP实现无限分类的实现方法
Nov 14 PHP
php获取ip及网址的简单方法(必看)
Apr 01 PHP
laravel 验证错误信息到 blade模板的方法
Sep 29 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
Feb 21 PHP
PHP flock 文件锁详细介绍
Dec 29 #PHP
PHP生成唯一的促销/优惠/折扣码(附源码)
Dec 28 #PHP
PHP中函数rand和mt_rand的区别比较
Dec 26 #PHP
php中unlink()、mkdir()、rmdir()等方法的使用介绍
Dec 21 #PHP
php和javascript之间变量的传递实现代码
Dec 19 #PHP
ajax php传递和接收变量实现思路及代码
Dec 19 #PHP
PHP编码转换函数 自动转换字符集支持数组转换
Dec 16 #PHP
You might like
一台收音机,让一家人都笑逐颜开!
2020/08/21 无线电
php中计算时间差的几种方法
2009/12/31 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
记录一次排查PHP脚本执行卡住的问题
2016/12/27 PHP
修改js Calendar日历控件 兼容IE9/谷歌/火狐
2013/01/04 Javascript
jquery插件之信息弹出框showInfoDialog(成功/错误/警告/通知/背景遮罩)
2013/01/09 Javascript
javascript中scrollTop详解
2015/04/13 Javascript
node.js操作mongodb学习小结
2015/04/25 Javascript
IE中document.createElement的iframe无法设置属性name的解决方法
2015/09/14 Javascript
Highcharts入门之基本属性
2016/08/02 Javascript
jquery过滤特殊字符',防sql注入的实现方法
2016/08/17 Javascript
Bootstrap表格使用方法详解
2017/02/17 Javascript
jquery鼠标悬停导航下划线滑出效果
2017/09/29 jQuery
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
浅析Vue中拆分视图层代码的5点建议
2019/08/15 Javascript
小程序实现横向滑动日历效果
2019/10/21 Javascript
在Vue中使用antv的示例代码
2020/06/29 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
[49:02]KG vs Infamous 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
python数据结构之二叉树的统计与转换实例
2014/04/29 Python
详解python里的命名规范
2018/07/16 Python
详解opencv Python特征检测及K-最近邻匹配
2019/01/21 Python
python函数与方法的区别总结
2019/06/23 Python
Django 接收Post请求数据,并保存到数据库的实现方法
2019/07/12 Python
python tkinter图形界面代码统计工具(更新)
2019/09/18 Python
Django在Model保存前记录日志实例
2020/05/14 Python
python 多进程和协程配合使用写入数据
2020/10/30 Python
CSS3中box-shadow的用法介绍
2015/07/15 HTML / CSS
世界首屈一指的钓鱼用品商店:TackleDirect
2016/07/26 全球购物
美国奢侈品购物平台:Orchard Mile
2018/05/02 全球购物
婴儿地球:Baby Earth
2018/12/25 全球购物
澳大利亚最好的电动自行车:Leon Cycle
2020/12/19 全球购物
你所知道的集合类都有哪些?主要方法?
2012/12/31 面试题
几个常见的消息中间件(MOM)
2014/01/08 面试题
工作失职检讨书
2015/01/26 职场文书
学校运动会简讯
2015/07/20 职场文书