给定表达式字符串exp,编写一个程序来检查exp中的
对和
"{","}","(",")","[","]"
的顺序是否正确。 />
例如,对于
exp = "[()]{}{[()()]()}"
该程序应打印true,对于
exp = "[(])"
该程序应打印false />
复杂度:
时间复杂度:\ $ O(n)\ $其中\ $ n \ $是字符串的长度
空间复杂度:\ $ O(\ frac {n} {2})\ $其中\ $ n \ $是字符串的长度
我看到了Java版本,并以为“我想提交JavaScript版本。”寻找代码审查,优化和最佳实践。
在我的版本中,字符串可以包含除括号以外的其他字符,
""
被接受为输入,并且我并不关心短路奇数长度的字符串。 function parenthesesAreBalanced(s)
{
var parentheses = "[]{}()",
stack = [], //Parentheses stack
i, //Index in the string
c; //Character in the string
for (i = 0; c = s[i++];)
{
var bracePosition = parentheses.indexOf(c),
braceType;
//~ is truthy for any number but -1
if (!~bracePosition)
continue;
braceType = bracePosition % 2 ? 'closed' : 'open';
if (braceType === 'closed')
{
//If there is no open parenthese at all, return false OR
//if the opening parenthese does not match ( they should be neighbours )
if (!stack.length || parentheses.indexOf(stack.pop()) != bracePosition - 1)
return false;
}
else
{
stack.push(c);
}
}
//If anything is left on the stack <- not balanced
return !stack.length;
}
console.log('{}([]) true', parenthesesAreBalanced('{}([])'));
console.log('{{ false', parenthesesAreBalanced('{{'));
console.log('[(]) false', parenthesesAreBalanced('[(])'));
console.log("{}([]) true", parenthesesAreBalanced("{}([])"));
console.log("([}]) false", parenthesesAreBalanced("([}])"));
console.log("([]) true", parenthesesAreBalanced("([])"));
console.log("()[]{}[][]", parenthesesAreBalanced("()[]{}[][]"));
#1 楼
这几乎是所有样式建议;代码本身看起来很棒。但是,这些只是偏好。我也跳过了按位操作,添加了一些严格的比较而不是!stack.length
等,将i++
移至其“常规”位置,并加长了一些变量名,以简化说明。再次:基本上这都是毫无意义的,但是我只是喜欢把东西拼出来。
唯一真正的区别是,我将期望的闭合括号的位置推到了堆栈上,而不是将开始括号推到了堆栈上。
function parenthesesAreBalanced(string) {
var parentheses = "[]{}()",
stack = [],
i, character, bracePosition;
for(i = 0; character = string[i]; i++) {
bracePosition = parentheses.indexOf(character);
if(bracePosition === -1) {
continue;
}
if(bracePosition % 2 === 0) {
stack.push(bracePosition + 1); // push next expected brace position
} else {
if(stack.length === 0 || stack.pop() !== bracePosition) {
return false;
}
}
}
return stack.length === 0;
}
更新:实际上,您可以跳过内部条件中的一个
stack.length
检查;实际上,您可以跳过一个stack.pop()
检查。如果堆栈为空,则undefined
只会返回q4312079q,所以这就足够了:if(stack.pop() !== bracePosition) {
return false;
}
评论
\ $ \ begingroup \ $
我非常喜欢推动bracePosition + 1,+ 1的想法
\ $ \ endgroup \ $
– konijn
2014年4月2日在12:11
#2 楼
我编写了一个称为Balanced的Node / JavaScript库,它可以完成更多操作,但是我使用的主要概念是使用堆栈,编译open
/ close
标签的正则表达式,然后进行1次传递。它似乎比indexOf
的执行要好。使用平衡的
isBalanced
方法编写方法的方式是例外:JSFiddle和以下示例忽略注释块JSFiddle
对于您的示例,
balanced
将产生以下错误function isBalanced(string) {
return !!balanced.matches({source: string, open: ['{', '(', '['], close: ['}', ')', ']'], balance: true});
}
评论
\ $ \ begingroup \ $
我喜欢你的回答。但是,有一些故障。我认为您应该改进它,使其更好地解析整个JS函数或FILE。例如:在您的JS小提琴上,我粘贴了一条包含.replace(/ [{] / g,“”).replace(/ [}] / g,“”)的JS行。它失败了。
\ $ \ endgroup \ $
– Manjeet
18-09-7在15:50
评论
添加此检查作为第一个验证,如果表达式的长度为奇数,我们可以立即返回false。@Ananda支持非大括号,“ abc”和“ o []”平衡且长度奇数