Javascript - 在字符串中添加缺少的括号

时间:2014-10-27 11:39:22

标签: javascript regex string

这是我的代码:

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))"

6 个答案:

答案 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)

这个似乎有效:

&#13;
&#13;
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;
&#13;
&#13;

答案 4 :(得分:0)

您可以在此处使用基于着名堆栈的括号匹配算法的变体。

一般的想法是你扫描代码并在看到代码时将一个左括号推到堆栈上,然后当你看到一个结束时,你从堆栈中弹出最高值并继续。这将确保您获得正确的余额。

(123())
// ( - push -> ['(']
// 1 - nothing
// 2 - nothing
// 3 - nothing
// ( - push -> ['(', '(']
// ) - pop -> ['(']
// ) - pop -> []

但是,我们想稍微改变规则。

  • 如果我们将一个关闭的paren推到堆栈上,并且堆栈是空的:我们需要在字符串的开头添加一个空格
  • 如果我们到达字符串的末尾并且堆栈上仍有打开的parens,那么我们需要关闭它们。

所以代码看起来像这样:

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;
};