具有错误字符容限的最长公共子串

2023-12-22

我在这里找到了一个脚本,在寻找最低公共子串时效果很好。

但是,我需要它来容忍一些不正确/丢失的字符。我希望能够输入所需的相似性百分比,或者指定允许的丢失/错误字符的数量。

例如,我想找到这个字符串:

大黄色校车

该字符串内部:

那天下午他们乘坐黄色大校车

这是我当前使用的代码:

function longest_common_substring($words) {
    $words = array_map('strtolower', array_map('trim', $words));
    $sort_by_strlen = create_function('$a, $b', 'if (strlen($a) == strlen($b)) { return strcmp($a, $b); } return (strlen($a) < strlen($b)) ? -1 : 1;');
    usort($words, $sort_by_strlen);

    // We have to assume that each string has something in common with the first
    // string (post sort), we just need to figure out what the longest common
    // string is. If any string DOES NOT have something in common with the first
    // string, return false.
    $longest_common_substring = array();
    $shortest_string = str_split(array_shift($words));

    while (sizeof($shortest_string)) {
        array_unshift($longest_common_substring, '');
        foreach ($shortest_string as $ci => $char) {
            foreach ($words as $wi => $word) {
                if (!strstr($word, $longest_common_substring[0] . $char)) {
                    // No match
                    break 2;
                }
            }
            // we found the current char in each word, so add it to the first longest_common_substring element,
            // then start checking again using the next char as well
            $longest_common_substring[0].= $char;
        }
        // We've finished looping through the entire shortest_string.
        // Remove the first char and start all over. Do this until there are no more
        // chars to search on.
        array_shift($shortest_string);
    }

    // If we made it here then we've run through everything
    usort($longest_common_substring, $sort_by_strlen);

    return array_pop($longest_common_substring);
}

任何帮助深表感谢。

UPDATE

PHP levenshtein 函数限制为 255 个字符,而我正在搜索的一些干草堆有 1000 多个字符。


将其写为第二个答案,因为它根本不是基于我之前的(糟糕的)答案。

这段代码基于http://en.wikipedia.org/wiki/Wagner%E2%80%93 费歇尔算法 http://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm and http://en.wikipedia.org/wiki/Approximate_string_matching#Problem_formulation_and_algorithms http://en.wikipedia.org/wiki/Approximate_string_matching#Problem_formulation_and_algorithms

给定 $needle,它返回 $haystack 的一个(可能是多个)最小编辑子字符串。现在,编辑距离只是编辑距离的一种度量,它实际上可能不适合您的需求。在这个指标上,“hte”更接近“he”,而不是“the”。我提供的一些示例显示了该技术的局限性。我相信这比我之前给出的答案要可靠得多,但请让我知道它对您有何作用。

// utility function - returns the key of the array minimum
function array_min_key($arr)
{
    $min_key = null;
    $min = PHP_INT_MAX;
    foreach($arr as $k => $v) {
        if ($v < $min) {
            $min = $v;
            $min_key = $k;
        }
    }
    return $min_key;
}

// Calculate the edit distance between two strings
function edit_distance($string1, $string2)
{
    $m = strlen($string1);
    $n = strlen($string2);
    $d = array();

    // the distance from '' to substr(string,$i)
    for($i=0;$i<=$m;$i++) $d[$i][0] = $i;
    for($i=0;$i<=$n;$i++) $d[0][$i] = $i;

    // fill-in the edit distance matrix
    for($j=1; $j<=$n; $j++)
    {
        for($i=1; $i<=$m; $i++)
        {
            // Using, for example, the levenshtein distance as edit distance
            list($p_i,$p_j,$cost) = levenshtein_weighting($i,$j,$d,$string1,$string2);
            $d[$i][$j] = $d[$p_i][$p_j]+$cost;
        }
    }

    return $d[$m][$n];
}

// Helper function for edit_distance()
function levenshtein_weighting($i,$j,$d,$string1,$string2)
{
    // if the two letters are equal, cost is 0
    if($string1[$i-1] === $string2[$j-1]) {
        return array($i-1,$j-1,0);
    }

    // cost we assign each operation
    $cost['delete'] = 1;
    $cost['insert'] = 1;
    $cost['substitute'] = 1;

    // cost of operation + cost to get to the substring we perform it on
    $total_cost['delete'] = $d[$i-1][$j] + $cost['delete'];
    $total_cost['insert'] = $d[$i][$j-1] + $cost['insert'];
    $total_cost['substitute'] = $d[$i-1][$j-1] + $cost['substitute'];

    // return the parent array keys of $d and the operation's cost
    $min_key = array_min_key($total_cost);
    if ($min_key == 'delete') {
        return array($i-1,$j,$cost['delete']);
    } elseif($min_key == 'insert') {
        return array($i,$j-1,$cost['insert']);
    } else {
        return array($i-1,$j-1,$cost['substitute']);
    }
}

// attempt to find the substring of $haystack most closely matching $needle
function shortest_edit_substring($needle, $haystack)
{
    // initialize edit distance matrix
    $m = strlen($needle);
    $n = strlen($haystack);
    $d = array();
    for($i=0;$i<=$m;$i++) {
        $d[$i][0] = $i;
        $backtrace[$i][0] = null;
    }
    // instead of strlen, we initialize the top row to all 0's
    for($i=0;$i<=$n;$i++) {
        $d[0][$i] = 0;
        $backtrace[0][$i] = null;
    }

    // same as the edit_distance calculation, but keep track of how we got there
    for($j=1; $j<=$n; $j++)
    {
        for($i=1; $i<=$m; $i++)
        {
            list($p_i,$p_j,$cost) = levenshtein_weighting($i,$j,$d,$needle,$haystack);
            $d[$i][$j] = $d[$p_i][$p_j]+$cost;
            $backtrace[$i][$j] = array($p_i,$p_j);
        }
    }

    // now find the minimum at the bottom row
    $min_key = array_min_key($d[$m]);
    $current = array($m,$min_key);
    $parent = $backtrace[$m][$min_key];

    // trace up path to the top row
    while(! is_null($parent)) {
        $current = $parent;
        $parent = $backtrace[$current[0]][$current[1]];
    }

    // and take a substring based on those results
    $start = $current[1];
    $end = $min_key;
    return substr($haystack,$start,$end-$start);
}

// some testing
$data = array( array('foo',' foo'), array('fat','far'), array('dat burn','rugburn'));
$data[] = array('big yellow school bus','they rode the bigyellow schook bus that afternoon');
$data[] = array('bus','they rode the bigyellow schook bus that afternoon');
$data[] = array('big','they rode the bigyellow schook bus that afternoon');
$data[] = array('nook','they rode the bigyellow schook bus that afternoon');
$data[] = array('they','console, controller and games are all in very good condition, only played occasionally. includes power cable, controller charge cable and audio cable. smoke free house. pes 2011 super street fighter');
$data[] = array('controker','console, controller and games are all in very good condition, only played occasionally. includes power cable, controller charge cable and audio cable. smoke free house. pes 2011 super street fighter');

foreach($data as $dat) {
    $substring = shortest_edit_substring($dat[0],$dat[1]);
    $dist = edit_distance($dat[0],$substring);
    printf("Found |%s| in |%s|, matching |%s| with edit distance %d\n",$substring,$dat[1],$dat[0],$dist);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有错误字符容限的最长公共子串 的相关文章

  • PHP 的 USORT 回调函数参数

    这是一个非常深奥的问题 但我真的很好奇 今天是我多年来第一次使用 usort 我对到底发生了什么特别感兴趣 假设我有以下数组 myArray array 1 9 18 12 56 我可以用 usort 对此进行排序 usort myArra
  • 将 mod-rewrite 添加到现有 PHP 网站

    我正在更新一个 php 应用程序 该应用程序当前不使用 url 重写 目的是隐藏文件扩展名 网站总体结构如下 root index php login php page1 php page2 php page3 php page4 php
  • 如何使用 JQuery 提取嵌套 HTML 中的文本?

    我这里有 HTML 代码 div class actResult style border solid table tbody tr td Order Number td td 1 td tr tr td Customer Number t
  • 如何获取与 PHP 中的日期数组相比最接近的日期

    这个帖子 https stackoverflow com questions 11012891 how to get most recent date from an array of dates几乎为我回答了这个问题 但我有一个特定的需求
  • 运行 shell 命令并将输出发送到文件?

    我需要能够通过 php 脚本修改我的 openvpn 身份验证文件 我已将我的 http 用户设置为免通 sudoer 因为这台机器仅在我的家庭网络中可用 我目前有以下命令 echo shell exec sudo echo usernam
  • PHP exec rm -Rf 不适用于子目录

    我试图删除特定文件夹中的所有内容 但它似乎不会影响子文件夹 但它应该 因为 bash 命令是从控制台执行的 system rm Rf some dir 该命令中不需要星号 如果要与文件一起删除目录 请同时删除斜杠 留下斜杠将删除文件 但保留
  • PHP 时区问题 |英国夏令时和格林威治标准时间

    我开发了一个应用程序 它记录某些记录的修改和创建时间 所以基本上我们使用time 保存更改时进行记录的功能 我在英国 所以我的时区必须是 GMT 然而在英国 我们使用夏令时 所以在夏天我们不再使用格林尼治标准时间 而是使用英国夏令时 我如何
  • 使用 chr + rand 生成随机字符 (A-Z)

    我使用以下命令生成 A Z 的随机字符 但它偶尔会生成 符号 知道如何防止这种情况吗 也许字符范围不正确 letter chr 64 rand 0 26 用这个就更方便了 大写 letter chr rand 65 90 小写 letter
  • 如何解码这个 JSON 字符串?

    这是我从 feed finder url 中得到的字符串 JSON 编码 updated 1265787927 id http www google com reader api 0 feed finder q u003dhttp itca
  • drupal 7 将实际内容存储在数据库中的哪里?

    我打开了 drupal 7 的数据库并在表中查找node node revisions and node types并且找不到 drupal 存储实际的位置body节点 内容 的 有人有线索吗 哦 我刚刚找到了 在 D7 中 他们实现了字段
  • WooCommerce:检查商品是否已在购物车中

    我从中发现了这个很棒的片段website https joebuckle me quickie woocommerce check if item already in cart 以下是检查购物车中是否存在特定产品的函数 function
  • PHP 5.4 PDO 无法使用旧的不安全身份验证连接到 MySQL 4.1+

    我知道有很多类似的问题 事实上我已经阅读了所有 9 个问题 但是 他们都没有解决我的问题 我有一个共享托管包 最低限度 我的包中包含域名和托管 MySQL 服务器的单独 IP 地址 为了开发 我正在使用http localhost 与 PH
  • PHP-向某些浏览器显示消息

    我已经搜索过这个 我发现的一切都超出了我的需要 我以前用 JavaScript 做过这个 但我真的更喜欢使用 PHP 我将如何根据访问者使用的浏览器向他们显示消息 Example IE 用户会看到 您正在使用 Internet Explor
  • laravel 正则表达式验证不起作用

    我刚刚开始使用 laravel 正在努力验证我的表单之一中的文本区域 文本区域用于用户简介 因此我只想允许使用字母 数字 空格和以下字符 这就是我所拥有的 validator Validator make Input all array b
  • 在脚本中使用未定义常量

    我搜索了该网站并看到了对用户应该在变量周围加上单引号的问题的修复 但我仍然有点困惑 错误 全部参考第28行 注意 使用未定义的常量 log id 假定为 log id 注意 使用未定义的常量 log username 假定为 log use
  • 控制器 HMVC 内的 CodeIgniter 负载控制器

    我在用着http github com philsturgeon codeigniter template http github com philsturgeon codeigniter template 对于模板 我尝试将其他控制器视图
  • 带单引号的 XPATH 查询[重复]

    这个问题在这里已经有答案了 有人知道如何解决这个问题吗 单引号让我陷入困境 nodes xml gt xpath item contains catalog Billy s Blogs title 我尝试以各种方式逃避它 但都抛出错误 no
  • 为什么 count 比 $count 差

    我只是在查看不同问题的答案以了解更多信息 我看到一个answer https stackoverflow com a 4891402 429850这表明在 php 中编写这样的做法是不好的做法 for i 0 i
  • PHP7.1上读取会话数据失败

    分享一个我遇到的问题 现已解决 在我的开发机器上 我使用 PHP 运行 IIS 我升级到 PHP7 突然我的代码不再工作 返回此错误 session start 读取会话数据失败 用户 路径 C WINDOWS temp 看起来像是权限问题
  • snappy wkhtmltopdf 包装器将生成的 html 文件发送到浏览器

    我像鼹鼠一样用谷歌搜索 但找不到正确的方法 我正在使用 WKHTMLTOPDF Wrapper Snappy 创建 PDF 如何将使用generateFromHtml方法生成的pdf直接发送到浏览器 这就是我想做的 header Conte

随机推荐

  • JAR 文件:为什么提取然后压缩 JAR 文件会创建与原始大小不同的文件?

    我试图编辑提取的 Eclipse 插件 jar 文件中的单个字节 我注意到 在我将文件重新压缩为 jar 后 生成的文件比原始文件大 仅 1 并且该插件不起作用 Eclipse 已启动 但在选择工作区后静默关闭 回滚到原来的插件可以让它成功
  • 删除 index.php 并处理两个 Codeigniter 站点的子域(当其中一个站点位于另一个站点时)

    我有两个 Codeigniter 站点 一个位于另一个站点的子目录中 我需要一些帮助来修改我的 htaccess 文件以从两者中删除 index php 第一个站点 http subdomain domain com存储在 home sit
  • 将 2D 数组传递给 C++ 函数

    我有一个函数 我想将可变大小的二维数组作为参数 到目前为止我有这个 void myFunction double myArray myArray x y 5 etc 我在代码中的其他地方声明了一个数组 double anArray 10 1
  • 使用裁剪工具进行图像裁剪的 Django 应用程序

    我需要一个在客户端裁剪图像的应用程序 我的意思是 使用像 Jcrop jquery 插件这样的裁剪工具 我找到了这个工具 django 图像裁剪器 https github com marazmiki django image croppe
  • CUDA/PTX 32 位与 64 位

    CUDA 编译器可以选择生成 32 位或 64 位 PTX 这些有什么区别呢 是不是像 x86 一样 NVidia GPU 实际上也有 32 位和 64 位 ISA 还是仅与主机代码有关 指针肯定是最明显的区别 http docs nvid
  • NanoHTTPD - 将 https 流转换为 http

    为了克服 Chromecast 对来自自认证 https 服务器 在我的例子中是 Subsonic 音乐服务器 进行流传输的限制 我正在利用已经作为我的 Android 应用程序的一部分运行的 NanoHTTPD 服务器实例 这个想法是从
  • 如何在 Dart 中将 RxInt 转换为 Int ||扑?

    我正在玩扑扑 我遇到错误并且没有得到任何正确的解决方案 在我的应用程序中 我有一些可观察的变量GetX https pub dev packages get控制器 当尝试应用某种格式然后在此处获取日志时 Exception caught b
  • Maven 3.0.4 NoSuchMethod:... java.lang.NoSuchMethodError:com.google.common.collect.ImmutableSet.copyOf(..)

    我已经安装了Maven 3 0 4 with Homebrew每当我运行mvn命令我得到以下信息 Exception in thread main java lang NoSuchMethodError com google common
  • OkHttp 对请求启用/禁用 gzip 压缩

    我在用着Retrofit管理我的请求并希望进行一些测试来检查使用或不使用 gzip 的请求大小 默认情况下OkHttp对请求执行 gzip 压缩 或者必须使用拦截器 https github com square okhttp wiki I
  • jQuery 文档就绪与窗口加载冲突?

    我正在尝试拼凑一个视频库 我正在使用 jQuery 制作滑出面板 这很简单 我还使用 jQuery 来滚动缩略图 他们都工作得很好 问题是我需要滚动缩略图在滑出面板内工作 但事实并非如此 我认为这与文档准备好和窗口加载两个功能有关 我不确定
  • Ruby 中引发异常与抛出异常有什么区别?

    Ruby 有两种不同的异常机制 Throw Catch 和 Raise Rescue 为什么我们有两个 什么时候应该使用其中一种而不是另一种 raise fail rescue and ensure handle errors 也称为例外情
  • 如何以编程方式更新客户商店信用

    我正在使用 Magento 版本 1 9 1 1 我需要更新客户的商店信用余额 我知道可以在 Magento 管理界面中执行此操作 但就我而言 我需要向服务器发出 HTTP 请求 并且实际上执行与通过 Magento 管理界面执行的操作相同
  • 将brew安装的库包含到XCode中

    我正在尝试使用 Raylib 创建游戏 我想使用 XCode 因为我认为库管理会像 Windows 上的 Visual Studio 一样简单 我安装了这个库brew install raylib 现在我尝试运行这个从 Raylib 网站复
  • apollo graphql 响应数据中未显示“Extensions”字段

    这里有一个可重现的例子 https github com stonecold123 typegraphql test Run app js并在操场上导航http localhost 4000 graphql http localhost 4
  • VBA 中的编辑距离 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有包含数据的 Excel 工作表 我想获取它们之间的 Levenshtein 距离 我已经尝试导出为文
  • 使用 Python 2.7 的 HTML 解析树

    我试图为下面的 HTML 表配置一棵解析树 但无法形成它 我想看看树结构是什么样的 有人可以帮助我吗 p class title b The Dormouse s story b p p class story Once upon a ti
  • Python:BASIC 中是否有相当于中、右、左的词?

    我想做这样的事情 gt gt gt mystring foo gt gt gt print mid mystring Help 切片来救援 def left s amount return s amount def right s amou
  • iText 通过检查 CRL 来验证签名

    我正在设置一个验证器 可以检查签名的有效性 我所做的签名基于 DSS 级别 LT 因此文档中内置了撤销检查 我现在遇到的问题是在我在iText中开发的验证器层面 它允许验证签名的有效性以及撤销信息的有效性 根据我的研究 IText 允许基于
  • 在 Vim 中查找 C++ 类成员的定义/引用

    我正在将 Vim 用于一个我已经开始从事的 C 项目 并且最近我花了很多时间浏览现有代码以掌握它的窍门 为了使浏览更容易 我在 Vim 中设置了 ctags 和 cscope 来跳转到定义并查找引用 然而 我发现他们都没有足够的智能来知道成
  • 具有错误字符容限的最长公共子串

    我在这里找到了一个脚本 在寻找最低公共子串时效果很好 但是 我需要它来容忍一些不正确 丢失的字符 我希望能够输入所需的相似性百分比 或者指定允许的丢失 错误字符的数量 例如 我想找到这个字符串 大黄色校车 该字符串内部 那天下午他们乘坐黄色