`

PHP相似度计算函数:levenshtein

    博客分类:
  • php
 
阅读更多

      与 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

 

 

源码分析

 

levenshtein() 属于标准函数,在/ext/standard/目录下有专门针对此函数实现的文件:levenshtein.c。

 

levenshtein()会根据参数个数选择实现方式,针对参数为2和参数为5的情况,都会调用 reference_levdist() 函数计算距离。其不同在于对后三个参数,参数为2时,使用默认值1。

 

并且在实现源码中我们发现了一个在文档中没有说明的情况: levenshtein() 函数还可以传递三个参数,其最终会调用 custom_levdist() 函数。它将第三个参数作为自定义函数的实现,其调用示例如下:

 

 

 echo levenshtein("Hello World","ello World", 'strsub');

 

执行会报Warning: The general Levenshtein support is not there yet。这是因为现在这个方法还没有实现,仅仅是放了一个坑在那。

 

reference_levdist() 函数的实现算法是一个经典的DP问题。

 

给定两个字符串x和y,求最少的修改次数将x变成y。修改的规则只能是如下三种之一:删除、插入、改变。
用a[i][j]表示把x的前i个字符变成y的前j个字符所需的最少操作次数,则状态转移方程为:

 

 

当x[i]==y[j]时:a[i][j]  = min(a[i-1][j-1], a[i-1][j]+1, a[i][j-1]+1);
当x[i]!=y[j]时:a[i][j] =  min(a[i-1][j-1], a[i-1][j], a[i][j-1])+1;

 

在用状态转移方程前,我们需要初始化(n+1)(m+1)的矩阵d,并让第一行和列的值从0开始增长。 扫描两字符串(nm级的),对比字符,使用状态转移方程,最终$a[$l1][$l2]为其结果。

 

简单实现过程如下:

 

 

<?PHP
    $s1 = "abcdd";
    $l1 = strlen($s1);
    $s2 = "aabbd";
    $l2 = strlen($s2);
 
 
    for ($i = 0; $i < $l1; $i++) {
        $a[0][$i + 1] = $i + 1;
    }
    for ($i = 0; $i < $l2; $i++) {
        $a[$i + 1][0] = $i + 1;
    }
 
    for ($i = 0; $i < $l2; $i++) {
        for ($j = 0; $j < $l1; $j++) {
            if ($s2[$i] == $s1[$j]) {
                $a[$i + 1][$j + 1] = min($a[$i][$j], $a[$i][$j + 1] + 1, $a[$i + 1][$j] + 1);
            }else{
                $a[$i + 1][$j + 1] = min($a[$i][$j], $a[$i][$j + 1], $a[$i + 1][$j]) + 1;
            }
        }
    }
 
    echo $a[$l1][$l2];
    echo "\n";
    echo levenshtein($s1, $s2);

 

在PHP的实现中,实现者在注释中很清楚的标明:此函数仅优化了内存使用,而没有考虑速度,从其实现算法看,时间复杂度为O(m×n)。其优化点在于将上面的状态转移方程中的二维数组变成了两个一组数组。简单实现如下:

 

 

<?PHP
    $s1 = "abcjfdkslfdd";
    $l1 = strlen($s1);
    $s2 = "aab84093840932bd";
    $l2 = strlen($s2);
 
    $dis = 0;
    for ($i = 0; $i <= $l2; $i++){
        $p1[$i] = $i;
    }
 
    for ($i = 0; $i < $l1; $i++){
        $p2[0] = $p1[0] + 1;
 
        for ($j = 0; $j < $l2; $j++){
            if ($s1[$i] == $s2[$j]){
                $dis = min($p1[$j], $p1[$j + 1] + 1, $p2[$j] + 1);
            }else{
                $dis = min($p1[$j] + 1, $p1[$j + 1] + 1, $p2[$j] + 1);  // 注意这里最后一个参数为$p2  
            }
            $p2[$j + 1] = $dis;
        }
        $tmp = $p1;
        $p1 = $p2;
        $p2 = $tmp;  
    }
 
    echo "\n";
    echo $p1[$l2];
    echo "\n";
    echo levenshtein($s1, $s2);

 

如上为PHP内核开发者对前面经典DP的优化,其优化点在于不停的复用两个一维数组,一个记录上次的结果,一个记录这一次的结果。如果按照PHP的 参数,分别给三个操作赋值不同的值,在上面的算法中将对应的1变成操作对应的值就可以了。 min函数的第一个参数对应的是修改,第二个参数对应的是删除,第三个参数对应的是添加。

 

 

Levenshtein distance说明

 

Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。不会拼读,可以叫它edit distance(编辑距离)。Levenshtein distance可以用来:

 

  • Spell checking(拼写检查)
  • Speech recognition(语句识别)
  • DNA analysis(DNA分析)
  • Plagiarism detection(抄袭检测) LD用mn的矩阵存储距离值。

原文:http://www.phppan.com/2012/12/php-levenshtein-function/

分享到:
评论

相关推荐

    关于PHP的相似度计算函数:levenshtein的使用介绍

    使用说明先看手册上 levenshtein() 函数的说明: levenshtein() 函数返回两个字符串之间的 Levenshtein 距离。 Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。...

    mysql-doctrine-levenshtein-function:levenshtein函数的Doctrine扩展与MySQL一起使用

    仅供参考,有许多替代/附加算法可计算语音相似度。 这绝对不是完整的列表: (也可以使用) 定义MySQL函数 来源: , 版权:Jason Rust 执行以下命令以在数据库中定义LEVENSHTEIN和LEVENSHTEIN_RATIO函数。 必须...

    php similar_text()函数的定义和用法

    php similar_text() 函数计算比较两个字符串的相似度,本文章向码农介绍php similar_text() 函数的基本使用方法和基本使用实例,感兴趣的码农可以参考一下。 定义和用法 similar_text() 函数计算两个字符串的相似度...

    PHP改进计算字符串相似度的函数similar_text()、levenshtein()

    在处理字符串相似度计算时,PHP提供了几个内置函数来帮助开发者。其中,`similar_text()`函数用于计算两个字符串之间的相似度百分比,而`levenshtein()`函数则可以计算出两个字符串之间的编辑距离,即它们需要进行...

    PHP levenshtein()函数用法讲解

    在PHP编程语言中,Levenshtein距离可以通过内置的levenshtein()函数来计算。这个函数能够返回两个字符串之间的Levenshtein距离,也就是说,它能够告诉我们需要通过多少步操作(替换、插入或删除字符)才能将一个字符...

    PHP中计算字符串相似度的函数代码

    在PHP中,计算字符串相似度有多种方法,其中最常用的两个函数是`similar_text`和`levenshtein`。这两个函数可以帮助开发者评估两个字符串之间的相似程度,特别是在文本处理、搜索优化或者数据清洗等场景中非常有用。...

    likestring简单的相似字符串处理库

    1. **字符串相似度算法**:该库可能实现了几种常见的字符串相似度计算方法,如Levenshtein距离、Jaccard相似度、Damerau-Levenshtein距离、Jaro-Winkler距离等。这些算法可以量化两个字符串之间的差异程度,帮助我们...

    PHP常用函数大全.pdf

    - `levenshtein` 计算两个字符串之间的Levenshtein距离,用于衡量字符串之间的相似度。 - `md5_file` 和 `md5` 用于生成字符串或文件内容的MD5散列值。 - `metaphone` 和 `soundex` 用于计算字符串的隐喻和声音编码...

    php常用函数集合

    `similar_text` – 字符串相似度计算 - **功能**:计算两个字符串之间的相似度百分比。 - **示例**: ```php similar_text("Hello", "Halo", $percent); echo $percent; // 输出: 60 ``` ##### 36. `soundex`...

    使用PHP similar text计算两个字符串相似度

    - 如果需要更高级的文本相似度计算,可以考虑使用更复杂的算法,如余弦相似度、Jaccard相似度或者更专业的自然语言处理库,如PHP的`TextBlob`或`PHP-ML`。 ### 实际应用示例 在网站开发中,`similar_text()`函数...

    php查询相似度最高的字符串的方法

    4. 实际应用案例:相似度查询不仅可以应用于校正用户输入错误,还能在许多其他场景中发挥作用,例如搜索引擎中的拼写纠错、生物信息学中的基因序列分析、自然语言处理中的语义相似度计算等。了解这些应用场景有助于...

    PHP常用函数解析

    - `levenshtein()`:计算两个字符串之间的Levenshtein距离,即编辑距离。 - `ltrim()`:移除字符串左侧的空格或指定字符。 - `md5_file()`:计算文件的MD5哈希值,用于文件完整性验证。 - `md5()`:计算字符串的...

    PHP常用函数大全.doc

    - **功能**: 计算两个字符串之间的相似度百分比。 - **示例**: `similar_text("hello", "hallo")` 返回 `80`。 #### 45. `soundex` - **功能**: 计算字符串的Soundex键。 - **示例**: `soundex("Smith")` 返回 `...

    php函数解析

    **功能**:计算两个字符串之间的Levenshtein距离。 **示例**: ```php echo levenshtein("kitten", "sitting"); // 输出: 3 ``` ##### localeconv () : array **功能**:获取当前区域设置的数字格式信息。 **示例**...

    PHP常用函数大全

    19. **levenshtein**: 计算两个字符串之间的莱文斯坦距离,即最小编辑距离,用于比较字符串的相似度,在搜索、拼写检查等领域有广泛的应用。 20. **localeconv**: 获取数字格式化信息,根据当前的本地设置调整数值...

    最全PHP常用函数解析

    `levenshtein()`计算两个字符串的编辑距离,用于识别字符串的相似度。`localeconv()`提供本地化格式信息,如数字和日期的显示格式。 `ltrim()`和`rtrim()`分别用于移除字符串左侧和右侧的空白字符。`md5_file()`和`...

    php常用函数[总结].pdf

    22. `levenshtein()`:计算两个字符串之间的Levenshtein距离,即最小编辑距离,表示将一个字符串转换成另一个需要的最少替换、插入或删除操作次数。 23. `localeconv()`:返回与当前本地设置相关的数字和货币格式...

Global site tag (gtag.js) - Google Analytics