这是一种不同的方法,与原帖和@nice_dev的答案不同,即构建一个查找表,以防需要进行多个有效性检查:
function generatePatterns(array $chars, int $minSize, int $maxSize): array {
$count = count($chars);
return array_map(
fn($value) => implode('', $value),
array_merge(
...array_map(
fn($value) => array_map(
fn($element) => array_map(
fn($item) => $chars[intdiv($element, $count ** $item) % $count],
$range = range(0, $value - 1)
),
range(0, ( count($chars) ** $value ) - 1)
),
range($minSize, $maxSize)
)
)
);
}
function getPatternsValidity(array $patterns): array {
return array_merge(
...array_map(
function ($pattern) {
$countOfStars = substr_count($pattern, '*') ?? 0;
if ($countOfStars === 0) {
$tests = [ [ $pattern ] ];
} else {
$tests = array_map(
fn($value) => str_split($value),
array_filter(
generatePatterns([ '(', ')', ' ' ], $countOfStars, $countOfStars),
fn($item) => count(str_split($item)) === $countOfStars
)
);
}
$retval[$pattern] = false;
foreach ($tests as $test) {
$testPattern = $pattern;
foreach ($test as $char) {
$offset = strpos($testPattern, '*');
if ($offset !== false) {
$testPattern = substr_replace($testPattern, $char, $offset, 1);
}
}
$sum = 0;
$runningSum = array_map(
function ($value) use (&$sum) {
if ($value === '(') return ++$sum;
if ($value === ')') return --$sum;
return 0;
},
str_split($testPattern)
);
if ($sum === 0 && min($runningSum) >= 0) {
$retval[$pattern] = true;
break;
}
}
return $retval;
},
$patterns
)
);
}
生成所有模式:
$allPatterns = generatePatterns([ '(', ')', '*' ], 1, 3);
print_r($allPatterns);
Array
(
[0] => (
[1] => )
[2] => *
[3] => ((
[4] => )(
[5] => *(
[6] => ()
[7] => ))
[8] => *)
[9] => (
[18] => )
[27] =>
[29] => **)
[30] => (
从生成的模式中构建模式/有效性对的数组:
$patternsValidity = getPatternsValidity($allPatterns);
print_r($patternsValidity);
Array
(
[(] =>
[)] =>
[*] => 1
[((] =>
[)(] =>
[*(] =>
[()] => 1
[))] =>
[*)] => 1
[(] =>
[)] =>
[] =>
[**)] => 1
[(
用作查找表的使用方法:
$isPatternValid1 = $patternsValidity['(*)'] ? 'yes' : 'no';
echo "isPatternValid1 '(*)' –> $isPatternValid1\n";
$isPatternValid2 = $patternsValidity[')**'] ? 'yes' : 'no';
echo "isPatternValid2 ')**' –> $isPatternValid2\n";
isPatternValid1 '(*)' –> yes
isPatternValid2 ')**' –> no
所有有效模式的数组:
$validPatterns = array_keys(array_filter($patternsValidity, fn($value) => $value, ARRAY_FILTER_USE_BOTH));
print_r($validPatterns);
Array
(
[0] => *
[1] => ()
[2] => *)
[3] =>
所有无效模式的数组:
$invalidPatterns = array_keys(array_filter($patternsValidity, fn($value) => !$value, ARRAY_FILTER_USE_BOTH));
print_r($invalidPatterns);
Array
(
[0] => (
[1] => )
[2] => ((
[3] => )(
[4] => *(
[5] => ))
[6] => )*
[7] => (((
[8] => )((
[9] => *((
[10] => ()(
[11] => ))(
[12] => *)(
[13] => )
[21] => )*)
[22] => (
*
也可以被视为空格值,还是只能替换为(
或)
? - nice_dev(()())
是有效的,因为在数学中每个开括号都有相应的闭括号,但如果我们改变顺序,那么就是无效的,比如)()()(
。@KevinY - Nauman Ilyas