这是我的代码:
function pars(str) {
var p = [str.split("(").length - 1, str.split(")").length - 1];
if (p[0] > p[1]) {
for (var i = 0; i < (p[0] - p[1]); i++) {
str += ")";
}
}
return str;
}
如果缺少括号,则在字符串的末尾添加括号。
示例:
"((asd)s" -> "((asd)s)"
"(((ss)123" -> "(((ss)123))"
我怎样才能开始括号的工作呢?
像:
"))" -> "(())"
")123))" -> "((()123))"
答案 0 :(得分:4)
这是一种简单的基于堆栈的方法。完整的JSFiddle以及确认的测试用例列表。
function pars(s) {
var missedOpen = 0, stack = new Array();
for (i = 0; i < s.length; i++) {
if (s[i] == '(') {
stack.push(s[i]);
} else if (s[i] == ')') {
if (!stack.pop())
missedOpen++;
}
}
return Array(missedOpen + 1).join('(') + s + Array(stack.length + 1).join(')');
}
确认的测试用例:
// Target: Expected
var cases = {
'()': '()',
')(': '()()',
'(': '()',
')': '()',
'This)(is))a((test)': '((This)(is))a((test))',
'(A)': '(A)',
')A(': '()A()'
};
See the complete JSFiddle is here
正如评论所指出的,这里是一个没有阵列的版本。这应该是最有效的方法。所有测试用例都通过了。
function pars(s) {
var missedOpen = 0, missedClosed = 0;
for (i = 0; i < s.length; i++) {
if (s[i] == '(') {
missedClosed++;
} else if (s[i] == ')') {
if (missedClosed > 0)
missedClosed--;
else
missedOpen++;
}
}
return Array(missedOpen + 1).join('(') + s + Array(missedClosed + 1).join(')');
}
答案 1 :(得分:1)
您需要不匹配的开头括号的数量和不匹配的结束括号的数量。这是一个粗略的解决方案:
function pars(str) {
var p = 0;
var minp = 0;
for (var i = 0; i < str.length; i++) {
if (str[i] == "(") p++;
if (str[i] == ")") {
p--;
if (p<minp) minp = p;
}
}
for (i = 0; i > minp; i--) {
str = "(" + str;
}
p = p - minp; // If we added any starting parenthesis, we need to end those as well.
for (i = 0; i < p; i++) {
str = str + ")";
}
return str;
}
答案 2 :(得分:0)
这是一个非常脏解决方案(由于repeat
功能暂时适用于Firefox):
function pars(str) {
var t = str;
var n;
while ((n = t.replace(/\([^()]*\)/g, "")) != t) {
t = n;
}
var open = t.match(/\)/g);
var close = t.match(/\(/g);
return "(".repeat(open.length) + str + ")".repeat(close.length);
}
基本上,它匹配所有()
对,然后计算(
和)
的数量,并相应地附加)
和(
。
干净的解决方案应该使用计数器来计算打开不匹配的括号的数量。它将丢弃并计算不匹配)
的数量。对于不匹配的(
的数量,按照正常情况进行操作。这将是一次性解决方案,而不是像上面那样的多次通过解决方案。
答案 3 :(得分:0)
这个似乎有效:
function pars(str){
var pars = [].reduce.call(str, function(acc, letter){
if(letter === '(') { acc.right++;}
else if(letter === ')') {
if(acc.right) {acc.right--;}
else {acc.left++;}//no starting one
}
return acc;
}, {left: 0, right: 0}),
left = pars.left,
right = pars.right;
if(left) { str = new Array(left+1).join('(') + str;}
if(right) { str += new Array(right+1).join(')');}
return str
}
var str = ')))(((fdfd)fd)('
$("#out").html(str + " - " + pars(str))
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="out"/>
&#13;
答案 4 :(得分:0)
您可以在此处使用基于着名堆栈的括号匹配算法的变体。
一般的想法是你扫描代码并在看到代码时将一个左括号推到堆栈上,然后当你看到一个结束时,你从堆栈中弹出最高值并继续。这将确保您获得正确的余额。
(123())
// ( - push -> ['(']
// 1 - nothing
// 2 - nothing
// 3 - nothing
// ( - push -> ['(', '(']
// ) - pop -> ['(']
// ) - pop -> []
但是,我们想稍微改变规则。
所以代码看起来像这样:
function parse(str) {
var stack = []
out = str,
idx = 0,
chr = '';
for(idx = 0; idx < str.length; idx++) {
chr = str[idx];
if(chr === '(') {
stack.push(chr);
}
else if(chr === ')') {
if(stack.length > 0) {
stack.pop();
} else {
out = '(' + out;
}
}
}
for(idx = 0; idx < stack.length; idx++) {
out = out + ')';
}
return out;
}
奖金:由于此算法基于迭代堆栈的性质,它通常会比RegEx替代品更快。
答案 5 :(得分:0)
只需扫描字符串,计算parens。 +1代表(,-1代表)。如果数字变为负数,那么你就错过了(在开始时。如果,当你完成时,数字是正数,那么这就是你需要在最后添加的数量。)
var addmissingparens = function(s){
var n = 0;
Array.prototype.forEach.call(s, function(c){
if(c === '('){
n += 1;
}
if(c === ')'){
if(n === 0){
s = '(' + s;
}else{
n -= 1;
}
}
});
for(; n>0; n-=1){
s += ')';
}
return s;
};