因此,让我们从使用循环和计数器的简单实现开始(仅用于递增):
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;
}
那么,它是如何工作的呢?基本上,它会循环通过,并检查字符的(ascii 数字)是否比它前面的字符多一个。如果是这样,它将增加 count 参数。否则,它会将其设置为 1(因为我们已经处理了该字符)。然后,如果大于或等于请求的数字,我们知道我们找到了一个序列,并且可以返回...ord
$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;
}
现在,它将返回 true for 和 ...abcd
dcba
现在,这里有一个更简单的解决方案:
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);
}