如果有一个善于PHP的人可以建议如何在表达式中验证括号,我会徘徊:
( 5 * 3 [ 6 ) - 6]
这是错误的表达方式。我需要一个功能来做到这一点。这是我到目前为止所尝试的:
<?php
function hasMatchedParenthesis($string) {
$counter1 = 0;
$counter2 = 0;
$length = strlen($string);
for ($i = 0;$i < $length; $i++) {
$char = $string[$i];
if( $char == '(' ) {
$counter1 ++;
} elseif( $char == ')' ) {
$counter1 --;
}
for($j =0;$j < $length; $j++) {
$char = $string[$j];
if( $char == '[' ) {
$counter2 ++;
} elseif( $char == ']' ) {
$counter2 --;
}
}
if( $counter1 < 0 || $counter2 < 0) {
return false;
}
}
echo 'ok';;
}
hasMatchedParenthesis('[5] * 3 - ( 4 - 7 * [3-6])'); // this is ok!
hasMatchedParenthesis('( 5 * 3 [ 6 ) - 6]'); // this returns as TRUE, but it is not!
?>
请帮助我解决'[6)'问题的验证!我不知道怎么做:(
答案 0 :(得分:9)
我想到的第一个想法是使用堆栈。 PHP提供了两个函数来将数组视为堆栈:array_push
和array_pop
。我们可以使用它们创建一堆0
(我们在一个开头(
内)和1
(我们在[
内),并在每个结束括号时匹配我们插入的最后一个值:
function hasMatchedParenthesis($string) {
$len = strlen($string);
$stack = array;
for ($i = 0; $i < $len; $i++) {
switch ($string[$i]) {
case '(': array_push($stack, 0); break;
case ')':
if (array_pop($stack) !== 0)
return false;
break;
case '[': array_push($stack, 1); break;
case ']':
if (array_pop($stack) !== 1)
return false;
break;
default: break;
}
}
return (empty($stack));
}
请注意,您可以将其扩展为包括{
和}
在内的任何其他字符对:
case '{': array_push($stack, 2); break;
case '}':
if (array_pop($stack) !== 2)
return false;
break;
答案 1 :(得分:1)
验证此类语法规则的常用方法是使用Context-free grammar - 请参阅examples,您将找到您正在尝试做的事情作为示例:-)并且您可以申请马克贝克指出,使用词法分析器这样的语法规则 在您的代码中,您只需要确保左括号的数量与右括号的数量相匹配,这就是缺陷。正如我在评论中指出的那样,你的最后一个条件应该是
if ($counter1 != 0 || $counter2 != 0){
return false;
}
在当前情况下,当任何计数器为true
时,将返回>=0
。尝试使用一个简单的案例hasMatchedParenthesis('[5] * 3 - ( 4 - 7 * [3-6');
,即使它出错也会返回true
。
答案 2 :(得分:0)
我在实现后写了。
function check_brackets_balance($string, $bracket_map = false) {
$bracket_map = $bracket_map ?: [ '[' => ']', '{' => '}', '(' => ')' ];
$bracket_map_flipped = array_flip($bracket_map);
$length = mb_strlen($string);
$brackets_stack = [];
for ($i = 0; $i < $length; $i++) {
$current_char = $string[$i];
if (isset($bracket_map[$current_char])) {
$brackets_stack[] = $bracket_map[$current_char];
} else if (isset($bracket_map_flipped[$current_char])) {
$expected = array_pop($brackets_stack);
if (($expected === NULL) || ($current_char != $expected)) {
return false;
}
}
}
return empty($brackets_stack);
}
它也使用堆栈,但代码较少,并为您自己的括号集提供了额外的参数。
check_brackets_balance('[5] * 3 - ( 4 - 7 * [3-6])'); // true
check_brackets_balance('( 5 * 3 [ 6 ) - 6]')); // false