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 相关文章推荐
Windows下PHP的任意文件执行漏洞
Oct 09 PHP
虚拟主机中对PHP的特殊设置
Oct 09 PHP
Thinkphp中的volist标签用法简介
Jun 18 PHP
用PHP生成excel文件到指定目录
Jun 22 PHP
thinkphp中的url跳转用法分析
Jul 12 PHP
PHP 搜索查询功能实现
Nov 29 PHP
ZendFramework2连接数据库操作实例
Apr 18 PHP
使用ThinkPHP生成缩略图及显示
Apr 27 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
Aug 28 PHP
Laravel创建数据库表结构的例子
Oct 09 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
PHP对接阿里云虚拟号的实现(号码隐私保护)
Apr 06 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
Windows下部署Apache+PHP+MySQL运行环境实战
2012/08/31 PHP
开源php中文分词系统SCWS安装和使用实例
2014/04/11 PHP
php编译安装php-amq扩展简明教程
2016/06/25 PHP
escape、encodeURI、encodeURIComponent等方法的区别比较
2006/12/27 Javascript
JQuery 学习笔记 选择器之二
2009/07/23 Javascript
JavaScript中对象property的读取和写入方法介绍
2014/12/30 Javascript
JavaScript学习笔记之JS事件对象
2015/01/22 Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
2015/03/04 Javascript
avalonjs实现仿微博的图片拖动特效
2015/05/06 Javascript
javascript控制台详解
2015/06/25 Javascript
轻量级javascript 框架Backbone使用指南
2015/07/24 Javascript
跨域资源共享 CORS 详解
2016/04/26 Javascript
Angular2 (RC4) 路由与导航详解
2016/09/21 Javascript
详解weex默认webpack.config.js改造
2018/01/08 Javascript
vue.js与element-ui实现菜单树形结构的解决方法
2018/04/21 Javascript
详解Vue.js自定义tipOnce指令用法实例
2018/12/19 Javascript
IDEA安装vue插件图文详解
2019/09/26 Javascript
webpack3升级到webpack4遇到问题总结
2019/09/30 Javascript
[00:16]热血竞技场
2019/03/06 DOTA
详解Python中的相对导入和绝对导入
2017/01/06 Python
python下setuptools的安装详解及No module named setuptools的解决方法
2017/07/06 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
python zip()函数使用方法解析
2019/10/31 Python
django教程如何自学
2020/07/31 Python
pandas抽取行列数据的几种方法
2020/12/13 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
html5-Canvas可以在web中绘制各种图形
2012/12/26 HTML / CSS
Cole Haan官方网站:美国时尚潮流品牌
2017/12/06 全球购物
施华洛世奇波兰官网:SWAROVSKI波兰
2019/06/18 全球购物
化学相关工作求职信
2013/10/02 职场文书
高中生自我鉴定范文
2013/10/30 职场文书
护理专业毕业生推荐信
2013/10/31 职场文书
《理想的风筝》教学反思
2014/04/11 职场文书
街道务虚会发言材料
2014/10/20 职场文书
2015年六一儿童节活动方案
2015/05/05 职场文书
python 用递归实现通用爬虫解析器
2021/04/16 Python