php - 检查字符串中是否有按字母顺序排列的字符

标签 php string

这似乎很明显,但我找不到这样做的方法。
我认为甚至有一个常规的 PHP 函数可以做到这一点,但即使是在 1.5 小时的密集 Google 搜索之后,该函数也能很好地隐藏。

我想要什么

  • 将字符串作为输入的函数。
  • 检查该字符串是否有超过 3 个字符的按字母顺序排列的序列的次数:
  • 如果找到超过 3 个的序列,则返回 true。

示例

"youlookgreatbcdetoday" => 里面有 "bcde"...所以必须返回 true
"youlookgreatklmtoday" => 里面只有 "klm"...所以必须返回 false
"youlookgreattoday" => 里面没有按字母顺序排列的序列,所以返回 false


可能的用例

  • 密码强度检查器
  • 文字游戏
  • ...

免责声明:我希望我已经有一些代码可以给你看,但实际上我什么都没有。
我唯一能想到的就是将字符串拆分在一个数组中并在数组上做一些魔法......但即便如此我还是被卡住了。

希望你们能救我:​​)

最佳答案

所以,让我们从一个使用循环和计数器(仅用于递增)的简单实现开始:

function hasOrderedCharactersForward($string, $num = 4) {
    $len = strlen($string);
    $count = 0;
    $last = 0;
    for ($i = 0; $i < $len; $i++) {
        $current = ord($string[$i]);
        if ($current == $last + 1) {
            $count++;
            if ($count >= $num) {
                return true;
            }
        } else {
            $count = 1;
        }
        $last = $current;
    }
    return false;
}

那么,它是如何工作的?基本上,它会循环并检查字符的 ord(ascii 编号)是否比它之前的一个多一个。如果是这样,它会增加计数参数。否则,它将其设置为 1(因为我们已经处理了该字符)。然后,如果 $count 大于或等于请求的数字,我们知道我们找到了一个序列,并且可以返回...

那么,现在让我们检查两个方向:

function hasOrderedCharacters($string, $num = 4) {
    $len = strlen($string);
    $count = 0;
    $dir = 1;
    $last = 0;
    for ($i = 0; $i < $len; $i++) {
        $current = ord($string[$i]);
        if ($count == 1 && $current == $last - 1) {
            $count++;
            $dir = -1;
            if ($count >= $num) {
                return true;
            }
        } elseif ($current == $last + $dir) {
            $count++;
            if ($count >= $num) {
                return true;
            }
        } else {
            $count = 1;
            $dir = 1;
        }
        $last = $current;
    }
    return false;
}

现在,abcddcba 将返回 true...

现在,这里有一个更简单的解决方案:

function hasOrderedCharactersForward($string, $num = 4) {
    $len = strlen($string) + 1;
    $array = array_map(
        function($m) use (&$len) {
            return ord($m[0]) + $len--;
        }, 
        str_split($string, 1)
    );
    $str = implode('_', $array);
    $regex = '#(^|_)(\d+)' . str_repeat('_\2', $num - 1) . '(_|$)#';
    return (bool) preg_match($regex, $str);
}

然后就可以了。我们使用的属性是,如果我们向每个位置添加一个递减的数字,则连续序列将显示为相同的数字。这正是它的工作原理。

这是适用于两个方向的相同理论:

function hasOrderedCharacters($string, $num = 4) {
    $i = 0;
    $j = strlen($string);
    $str = implode('', array_map(function($m) use (&$i, &$j) {
        return chr((ord($m[0]) + $j--) % 256) . chr((ord($m[0]) + $i++) % 256);
    }, str_split($string, 1)));
    return preg_match('#(.)(.\1){' . ($num - 1) . '}#', $str);
}

关于php - 检查字符串中是否有按字母顺序排列的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12124803/

相关文章:

php - 多行单引号字符串

php - 使用表单更新 Laravel 数据库

php - 回显两个用户

php - HTML 使用 Codeigniter 3 选择标签标题

string - 如何在 Swift 中将 NSHTTPURLResponse 转换为字符串

c++ - 如何用整数解析字符串?

swift - 填充一个用于打印的快速字符串

java - 如何用随机字符串填充二维数组

php - 使用一个公共(public)字段从列获取数据?

java - 从字符串中删除指定字符