How to add parentheses in javascript

This is my code:

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

It adds parentheses in the end of the string if it's missing.

Examples:

"[[asd]s" -> "[[asd]s]"
"[[[ss]123" -> "[[[ss]123]]"

How can I make this work for beginning parentheses aswell?

Like:

"]]" -> "[[]]"
"]123]]" -> "[[[]123]]"

asked Oct 27, 2014 at 11:39

3

Here is a simple stack-based approach. The full JSFiddle is below as well as list of confirmed test cases.

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[']'];
}

Confirmed Test cases:

// Target: Expected
var cases = {
    '[]': '[]',
    '][': '[][]',
    '[': '[]',
    ']': '[]',
    'This][is]]a[[test]': '[[This][is]]a[[test]]',
    '[A]': '[A]',
    ']A[': '[]A[]'
};

See the complete JSFiddle is here.

As noted by a comment, here's a version without the array at all. This should be the most efficient method. All the test cases passed.

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[']'];
}

answered Oct 27, 2014 at 12:48

Jason WJason W

12.8k3 gold badges27 silver badges58 bronze badges

2

You need both the number of unmatched beginning parenthesis and the number of unmatched end parenthesis. Here is a rough solution:

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

answered Oct 27, 2014 at 12:15

Klas LindbäckKlas Lindbäck

32.8k4 gold badges57 silver badges81 bronze badges

1

This one seems to work:

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]]

answered Oct 27, 2014 at 12:15

Yury TarabankoYury Tarabanko

42.7k9 gold badges82 silver badges96 bronze badges

This is an extremely dirty solution [which works in Firefox for the time being due to repeat function]:

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

Basically, it matches all pairs of [], then count the number of [ and ], and append ] and [ accordingly.

A clean solution should use a counter to count the number of opening unmatched parentheses. It will discard and count the number of unmatched ]. For the number of unmatched [, do as per normal. It will be a one-pass solution, instead of multi-pass solution like the one above.

answered Oct 27, 2014 at 12:05

nhahtdhnhahtdh

55k15 gold badges121 silver badges158 bronze badges

1

You can use a variation on the famous stack based bracket matching algorithm here.

The general idea is that you scan the code and push an opening parenthesis onto the stack when you see one, then when you see a closing one you pop the top value from the stack and continue. This will ensure that you have the correct balance.

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

However, we want to bend the rules slightly.

  • If we push a closing paren onto the stack, and the stack is empty: we need to add an opening paren to the start of the string
  • If we arrive at the end of the string and there are still open parens on the stack, then we need to close them.

So the code would look something like this:

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

Bonus: Because of the iterative stack based nature of this algorithm, it will generally be faster than RegEx alternatives.

answered Oct 27, 2014 at 12:27

Dan PrinceDan Prince

28.7k12 gold badges88 silver badges117 bronze badges

4

Just scan the string, counting parens. +1 for [, -1 for ]. If the number goes negative, you're missing a [ at the beginning. If, when you are finished, the number is positive, then that's how many ]s you need to add at the end.

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

answered Oct 27, 2014 at 12:41

19831983

5,7722 gold badges26 silver badges39 bronze badges

Chủ Đề