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 sprintf()函数用例解析
May 18 PHP
PHP对象转换为数组函数(递归方法)
Feb 04 PHP
探讨php中header的用法详解
Jun 07 PHP
php数组中包含中文的排序方法
Jun 03 PHP
php基于base64解码图片与加密图片还原实例
Nov 03 PHP
php中in_array函数用法分析
Nov 15 PHP
百度工程师讲PHP函数的实现原理及性能分析(二)
May 13 PHP
php实现遍历多维数组的方法
Nov 25 PHP
php blowfish加密解密算法
Jul 02 PHP
ThinkPHP3.2框架使用addAll()批量插入数据的方法
Mar 16 PHP
PHP实现的超长文本分页显示功能示例
Jun 04 PHP
php设计模式之适配器模式原理、用法及注意事项详解
Sep 24 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
Yii 快速,安全,专业的PHP框架
2014/09/03 PHP
jquery+php实现导出datatables插件数据到excel的方法
2015/07/06 PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
2017/11/12 PHP
使用laravel和ECharts实现折线图效果的例子
2019/10/09 PHP
javascript据option的value值快速设定初始的selected选项
2007/08/13 Javascript
SWFObject Flash js调用类
2008/07/08 Javascript
HTML上传控件取消选择
2013/03/06 Javascript
原生js操作checkbox用document.getElementById实现
2013/10/12 Javascript
Blocksit插件实现瀑布流数据无限( 异步)加载
2014/06/20 Javascript
jQuery中odd选择器的定义和用法
2014/12/23 Javascript
js淡入淡出焦点图幻灯片效果代码分享
2015/09/08 Javascript
js实现的动画导航菜单效果代码
2015/09/10 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
原生js实现addclass,removeclass,toggleclasss实例
2016/11/24 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
vue input输入框模糊查询的示例代码
2018/05/22 Javascript
VueJS 取得 URL 参数值的方法
2019/07/19 Javascript
图文讲解选择排序算法的原理及在Python中的实现
2016/05/04 Python
python xlsxwriter创建excel图表的方法
2018/06/11 Python
Python使用字典的嵌套功能详解
2019/02/27 Python
Python操作MySQL数据库实例详解【安装、连接、增删改查等】
2020/01/17 Python
python同义词替换的实现(jieba分词)
2020/01/21 Python
PyQt5 界面显示无响应的实现
2020/03/26 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
2020/10/29 Python
Gweniss格温妮丝女包官网:英国纯手工制造潮流包包品牌
2018/02/07 全球购物
Invicta手表官方商店:百年制表历史的瑞士腕表品牌
2019/09/26 全球购物
创业计划书——互联网商机
2014/01/12 职场文书
小学英语课后反思
2014/04/26 职场文书
教师演讲稿大全
2014/05/16 职场文书
食堂标语大全
2014/06/11 职场文书
扬尘污染防治方案
2014/06/15 职场文书
2014年圣诞节寄语
2014/12/08 职场文书
MySQL 十大常用字符串函数详解
2021/06/30 MySQL
Nginx反向代理至go-fastdfs案例讲解
2021/08/02 Servers
关于Python中*args和**kwargs的深入理解
2021/08/07 Python