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 相关文章推荐
全世界最小的php网页木马一枚 附PHP木马的防范方法
Oct 09 PHP
PHP 变量类型的强制转换
Oct 23 PHP
AMFPHP php远程调用(RPC, Remote Procedure Call)工具 快速入门教程
May 10 PHP
joomla内置的表单验证功能使用方法
Jun 11 PHP
PHP 多维数组排序(usort,uasort)
Jun 30 PHP
PHP处理excel cvs表格的方法实例介绍
May 13 PHP
解析php中的fopen()函数用打开文件模式说明
Jun 20 PHP
php判断页面是否是微信打开的示例(微信打开网页)
Apr 25 PHP
PHP 验证身份证是否合法的函数
Feb 09 PHP
PHP isset()与empty()的使用区别详解
Feb 10 PHP
php数值转换时间及时间转换数值用法示例
May 18 PHP
在Laravel中实现使用AJAX动态刷新部分页面
Oct 15 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
php中的strpos使用示例
2014/02/27 PHP
php中数据库连接方式pdo和mysqli对比分析
2015/02/25 PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
2015/05/13 PHP
[原创]静态页面也可以实现预览 列表不同的显示方式
2006/10/14 Javascript
javascript 文档的编码问题解决
2009/03/01 Javascript
javascript学习笔记(三)显示当时时间的代码
2011/04/08 Javascript
html超链接打开窗口大小的方法
2013/03/05 Javascript
javascript实例分享---具有立体效果的图片特效
2014/06/08 Javascript
浅析node.js中close事件
2014/11/26 Javascript
简单封装js的dom查询实例代码
2016/07/08 Javascript
jQuery设置Easyui校验规则(推荐)
2016/11/21 Javascript
深究AngularJS中ng-drag、ng-drop的用法
2017/06/12 Javascript
angular.js中解决跨域问题的三种方式
2017/07/12 Javascript
Angularjs cookie 操作实例详解
2017/09/27 Javascript
javascript 开发之网页兼容各种浏览器
2017/09/28 Javascript
vue 实现setInterval 创建和销毁实例
2020/07/21 Javascript
小程序实现列表展开收起效果
2020/07/29 Javascript
[33:19]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第一场 11.26
2020/11/30 DOTA
Python正则表达式实现简易计算器功能示例
2019/05/07 Python
简单了解python中的f.b.u.r函数
2019/11/02 Python
Python Django2 model 查询介绍(条件、范围、模糊查询)
2020/03/16 Python
python使用pymongo与MongoDB基本交互操作示例
2020/04/09 Python
Pandas对DataFrame单列/多列进行运算(map, apply, transform, agg)
2020/06/14 Python
使用CSS3和Checkbox实现JQuery的一些效果
2015/08/03 HTML / CSS
有750多个顶级品牌的瑞士时尚在线:ABOUT YOU
2017/01/04 全球购物
澳大利亚在线百货商店:Real Smart
2017/08/13 全球购物
美体小铺奥地利官方网站:The Body Shop奥地利
2019/04/11 全球购物
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
Bonami斯洛伐克:购买家具和家居饰品
2019/07/02 全球购物
Linux的主要特性
2016/09/03 面试题
机关门卫制度
2014/02/01 职场文书
2015年事业单位办公室文员工作总结
2015/04/24 职场文书
2015年学校总务处工作总结
2015/05/19 职场文书
离职信范文
2015/06/23 职场文书
pytorch中的model.eval()和BN层的使用
2021/05/22 Python
Win11怎样将锁屏账户头像图片改成动画视频
2021/11/21 数码科技