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 相关文章推荐
在线增减.htpasswd内的用户
Oct 09 PHP
MYSQL数据库初学者使用指南
Nov 16 PHP
php小型企业库存管理系统的设计与实现代码
May 16 PHP
提高php运行速度的一些小技巧分享
Jul 03 PHP
基于PHP选项与信息函数的使用详解
May 10 PHP
ThinkPHP的RBAC(基于角色权限控制)深入解析
Jun 17 PHP
destoon整合ucenter后注册页面不跳转的解决方法
Jun 21 PHP
PHP使用array_multisort对多个数组或多维数组进行排序
Dec 16 PHP
php 使用array函数实现分页
Feb 13 PHP
PHP简单生成缩略图相册的方法
Jul 29 PHP
php结合redis高并发下发帖、发微博的实现方法
Dec 15 PHP
PHP常用算法和数据结构示例(必看篇)
Mar 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中获取内网用户MAC地址(WINDOWS/linux)的实现代码
2011/08/11 PHP
基于session_unset与session_destroy的区别详解
2013/06/03 PHP
php自定义分页类完整实例
2015/12/25 PHP
PHP实现通过URL提取根域名
2016/03/31 PHP
PHP抓取淘宝商品的用户晒单评论+图片+搜索商品列表实例
2016/04/14 PHP
PHP处理二进制数据的实现方法
2016/06/13 PHP
Yii框架结合sphinx,Ajax实现搜索分页功能示例
2016/10/18 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
2019/05/27 PHP
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
setAttribute 与 class冲突解决
2008/02/17 Javascript
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
2009/11/28 Javascript
一个简单的jquery的多选下拉框(自写)
2014/05/05 Javascript
完美兼容各大浏览器的jQuery仿新浪图文淡入淡出间歇滚动特效
2014/11/12 Javascript
5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
2015/01/29 Javascript
Javascript动态创建div的方法
2015/02/09 Javascript
javascript每日必学之条件分支
2016/02/17 Javascript
浅谈JS使用[ ]来访问对象属性
2016/09/21 Javascript
浅谈JS如何实现真正的对象常量
2017/06/25 Javascript
自定义类似于jQuery UI Selectable 的Vue指令v-selectable
2017/08/23 jQuery
微信小程序滑动选择器的实现代码
2018/08/10 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
vue不操作dom实现图片轮播的示例代码
2019/12/18 Javascript
Python脚本暴力破解栅栏密码
2015/10/19 Python
浅谈django开发者模式中的autoreload是如何实现的
2017/08/18 Python
python ChainMap 合并字典的实现步骤
2019/06/11 Python
python中字符串数组逆序排列方法总结
2019/06/23 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
python redis存入字典序列化存储教程
2020/07/16 Python
python3从网络摄像机解析mjpeg http流的示例
2020/11/13 Python
写自荐信的七个技巧
2013/10/15 职场文书
行政人事经理职位说明书
2014/03/05 职场文书
学生安全承诺书
2014/05/22 职场文书
主要负责人任命书
2014/06/06 职场文书
2014年信贷员工作总结
2014/11/18 职场文书
2014年个人技术工作总结
2014/12/08 职场文书
超市啤酒狂欢夜策划方案范文!
2019/07/03 职场文书