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下实现在指定目录搜索指定类型文件的函数
Oct 03 PHP
php fckeditor 调用的函数
Jun 21 PHP
php后台多用户权限组思路与实现程序代码分享
Feb 13 PHP
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
Jul 18 PHP
PHP实现C#山寨ArrayList的方法
Jul 16 PHP
php 参数过滤、数据过滤详解
Oct 26 PHP
浅析php设计模式之数据对象映射模式
Mar 03 PHP
py文件转exe时包含paramiko模块出错解决方法
Aug 12 PHP
使用Codeigniter重写insert的方法(推荐)
Mar 23 PHP
CI框架(CodeIgniter)操作redis的方法详解
Jan 25 PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
May 23 PHP
laravel数据库查询结果自动转数组修改实例
Feb 27 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
纯真IP数据库的应用 IP地址转化成十进制
2009/06/14 PHP
PHP与MYSQL中UTF8编码的中文排序实例
2014/10/21 PHP
php实现三级级联下拉框
2016/04/17 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
js利用div背景,做一个竖线的效果。
2008/11/22 Javascript
JavaScript中的闭包原理分析
2010/03/08 Javascript
jquery 年会抽奖程序
2011/12/22 Javascript
js实现超简单的展开、折叠目录代码
2015/08/28 Javascript
AngularJs中route的使用方法和配置
2016/02/04 Javascript
jQuery实现鼠标经过像翻页和描点链接效果
2016/08/08 Javascript
JS动态计算移动端rem的解决方案
2016/10/14 Javascript
Javascript设计模式之装饰者模式详解篇
2017/01/17 Javascript
vue中各组件之间传递数据的方法示例
2017/07/27 Javascript
Validform验证时可以为空否则按照指定格式验证
2017/10/20 Javascript
解决node.js含有%百分号时发送get请求时浏览器地址自动编码的问题
2019/11/20 Javascript
[01:38]完美世界DOTA2联赛PWL S3 集锦第四期
2020/12/21 DOTA
python 判断一个进程是否存在
2009/04/09 Python
JSONLINT:python的json数据验证库实例解析
2017/11/28 Python
在matplotlib的图中设置中文标签的方法
2018/12/13 Python
pyqt5实现按钮添加背景图片以及背景图片的切换方法
2019/06/13 Python
python 求10个数的平均数实例
2019/12/16 Python
python能在浏览器能运行吗
2020/06/17 Python
pytorch随机采样操作SubsetRandomSampler()
2020/07/07 Python
全球游戏Keys和卡片市场:GamesDeal
2018/03/28 全球购物
设计部经理的岗位职责
2013/11/16 职场文书
党员干部民主生活会议批评与自我批评材料
2014/09/20 职场文书
党员群众路线自我剖析材料
2014/10/06 职场文书
欢迎新生标语
2014/10/06 职场文书
销售会议开幕词
2015/01/28 职场文书
前台接待员岗位职责
2015/04/15 职场文书
企业党建工作总结2015
2015/05/26 职场文书
慰问信(范文3篇)
2019/10/23 职场文书
Python 把两层列表展开平铺成一层(5种实现方式)
2021/04/07 Python
使用Redis实现点赞取消点赞的详细代码
2022/03/20 Redis
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers