在我工作的时候,我找到了一个很好的谜题,要求创建一个与{,(,[带有相应的大括号],)的正确匹配大括号的函数,}
他们提供的表达式的示例如下:
$expressions = array(")(){}","[]({})","([])","{()[]}","([)]");
必须返回的值是:
0
1
1
1
0
它们提供的约束是字符串的最大长度为100,并且数组可能携带至少50,000个元素。鉴于这些情况,他们希望该功能能在不到2秒的时间内解决问题。
我试着写一些东西,可以在这里找到(它是不完整的,因为我觉得整个if / else方法使它太毛茸茸 - 换句话说,它肯定需要超过2秒才能解决问题):
https://gist.github.com/adibbehjat/6387415
<?php
function check_braces($expressions) {
for($x = 0; $x < count($expressions); $x++)
{
$open = array("{", "[", "(");
$close = array("}", "]", ")");
$key = array("{" => "}", "[" => "]", "(" => ")");
$string = $expressions[$x];
echo $string."<br>";
//First item should open a brace, else fail
if((in_array($string[0], $close)) && (strlen($string) % 2))
{
echo 0;
echo '<br>';
}
else
{
$bank_o = array();
$bank_c = array();
$element = array();
for($y = 0; $y < strlen($string); $y++)
{
$element = $string[$y];
if(in_array($element, $open))
{
array_push($bank_o, $element);
}
else
{
array_push($bank_c, $element);
}
$arraycounter = array_merge($bank_o, $bank_c);
$y++;
if(!empty($bank_c) && !empty($bank_o))
{
$num = count($bank_o);
if($bank_c[0] == $key[$bank_o[$num - 1]])
{
array_shift($bank_c);
array_pop($bank_o);
}
}
elseif (empty($bank_c) && empty($bank_o)) {
echo 1 . "<br>";
}
else
{
}
}
}
}
}
//$expressions = array(")(){}","[]({})","([])","{()[]}","([)]");
$expressions = array("([])","([)]");
check_braces($expressions);
?>
我自己学习PHP,并且觉得我在确定最佳算法以解决此类问题方面缺乏很多技巧。并且很想知道其他替代方法是可行的。
答案 0 :(得分:3)
<?php
function checkMatchingBraces($expression) {
static $braces = [
'(' => ')',
'{' => '}',
'[' => ']'
];
$stack = [];
$state = null; // $state is only used for efficiency,
// would need to call end($stack) a lot otherwise
for ($i = 0, $length = strlen($expression); $i < $length; $i++) {
$char = $expression[$i];
if (isset($braces[$char])) {
// opening brace, pushing onto stack
$stack[] = $state = $char;
} else if ($state && $char == $braces[$state]) {
// matching closing brace to current state, popping stack
array_pop($stack);
$state = end($stack);
} else {
// non-matching brace
return false;
}
}
// expecting stack to be reduced back to 0 here, otherwise fail
return count($stack) == 0;
}
$expressions = array(")(){}","[]({})","([])","{()[]}","([)]");
var_dump(array_map('checkMatchingBraces', $expressions));
答案 1 :(得分:0)
function validBraces($braces) {
if (!is_string($braces))
return 0;
if (trim($braces, '(){}[]') !== '')
return 0;
$pile = array();
for ($i = 0; $i < strlen($braces); $i++) {
//App possible Closures
if ($braces[$i] === ')' || $braces[$i] === ']' || $braces[$i] === '}') {
$last = array_pop($pile);
if ($braces[$i] === ')' && $last !== '(' || $braces[$i] === '}' && $last !== '{' || $braces[$i] === ']' && $last !== '[')
return 0;
} else
$pile[] = $braces[$i];
}
return !$pile;
}
从Code Review返回p,如果为true,则返回1,如果为false,则返回0。
答案 2 :(得分:0)
功能1-如果您不喜欢正则表达式(Demo)
function is_valid($string) {
do {
$string = str_replace(['()', '{}', '[]'], '', $string, $count);
} while ($count);
return (int)!$string;
}
功能2-如果递归模式的想法吓到了您(Demo)
function is_valid($string) {
while (($string = preg_replace('~(?:\(\)|\{}|\[])+~', '', $string, -1, $count)) && $count);
return (int)!$string;
}
功能#3-Casimir et Hippolyte的very clever recursive pattern(Demo)
function is_valid($string) {
return preg_match('~(\((?1)*+\)|\[(?1)*+]|{(?1)*+})*\z~A', $string);
}
以下是一些示例输入和迭代的函数调用:
$expressions = array(")(){}", "[]({})", "([])", "{()[]}", "([)]", "{()[]}{()[]}{()[]}{()[]}{()[]}");
foreach ($expressions as $expression) {
echo "$expression is " , is_valid($expression) , "\n";
}
所有输出:
)(){} is 0
[]({}) is 1
([]) is 1
{()[]} is 1
([)] is 0
{()[]}{()[]}{()[]}{()[]}{()[]} is 1