【问题标题】:Validation Challenge: Does string contain all characters in character mask as a continuous substring?验证挑战:字符串是否包含字符掩码中的所有字符作为连续子字符串?
【发布时间】:2022-07-22 15:16:20
【问题描述】:

给定一个仅由小写字母组成的 haystack 字符串(单个单词)和一个仅包含唯一小写字母的字符掩码,确定字符掩码中的所有字母是否在 haystack 字符串中的任何点连续出现。字符掩码中的字母可以按任何顺序使用,如有必要,可以多次使用以形成限定字符串。

测试字符串和注释的预期布尔结果:

$tests = [
    ['word' => 'example',     'mask' => 'lmp'],   // true  (mpl)
    ['word' => 'goodness',    'mask' => 'dns'],   // false (dn, ss)
    ['word' => 'slippers',    'mask' => 'eip'],   // true  (ippe)
    ['word' => 'slippers',    'mask' => 'ips'],   // false (s, ipp, s)
    ['word' => 'google',      'mask' => 'go'],    // true  (goog)
    ['word' => 'food',        'mask' => 'go'],    // false (oo)
    ['word' => 'bananas',     'mask' => 'ans'],   // true  (ananas)
    ['word' => 'candle',      'mask' => 'ace'],   // false (ca, e)
    ['word' => 'mississippi', 'mask' => 'i'],     // true  (i)
    ['word' => 'executive',   'mask' => 'ecitx'], // false (exec, ti, e)
];

我对优雅、高效和/或抽象的答案感兴趣,作为富有想象力的编程练习。玩得开心!

关于 Stack Overflow 的许多预先存在的问题涉及各种具有相似要求的语言,但它们没有相同的规则组合。在这种情况下,限定子字符串必须完全由掩码中的字符组成,并且掩码中的所有字符必须至少使用一次。

这个问题是另一个用户an interesting but incomplete question被Roomba关闭、放弃、删除后的抢救操作。
我随意添加了细节来澄清任务,限制范围,并填充了一个一组测试用例。

【问题讨论】:

    标签: php string validation substring character


    【解决方案1】:
    1. 我的第一个创作使用preg_match_all() 提取连续的限定字符,然后使用提取的字母从字符掩码中删除字符。

      preg_match_all("/[$mask]+/", $word, $m)
      && array_filter($m[0], fn($chars) => !ltrim($mask, $chars))
      
    2. 然后我意识到preg_match_all() 可能是匹配的子字符串,因为它们没有足够的长度来清除掩码字符,所以可以更早地消除这些子字符串。我根据掩码的长度向正则表达式添加了一个最小量词。与降低的模式可读性相比,额外的函数调用可能值得,也可能不值得。

      preg_match_all("/[$mask]{" . strlen($mask) . ",}/", $word, $m)
      && array_filter($m[0], fn($chars) => !ltrim($mask, $chars))
      
    3. 最后,我想看看是否可以仅使用正则表达式完成任务,并避免进行不必要的剩余匹配。使用一种通常用于验证密码强度的技术,我调用了preg_replace() 来生成一系列前瞻,并构建了一个preg_match() 可以用来确保来自掩码的每个字母都存在于隔离子字符串中的模式。

      (bool) preg_match('/' . preg_replace('/[a-z]/', "(?=[$mask]*$0)", $mask) . "[$mask]+/", $word)
      

    关于哪一个最易读/最不可读/可维护的意见会有所不同,我没有执行任何基准测试来查看哪一个表现最好。这是PHP demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2019-06-07
      • 2011-11-09
      • 2013-05-18
      • 2022-01-13
      相关资源
      最近更新 更多