Join the Stack Overflow Community
Stack Overflow is a community of 6.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have written the logic to check for parenthesis for "(" and ")" but there seems to an issue when parenthesis gets mixed. This is because I'm just comparing the total parenthesis count.

This is what i wrote

function checkParanthesis(str){
  var depth=0;
  for(var i in str){
    if(str[i] == "(" || str[i] == "{" || str[i] == "[")
      depth++;
    else if(str[i] == ")" || str[i] == "}" || str[i] == "]")
      depth--;
  }
  
  if(depth !==0) return false;
  
  return true;
}

console.log(checkParanthesis("() test"));

Question:

But how can I check for multiple parenthesis elements? (){}[]

For example,

Input:

"[(]) abcd" // should return false
"[{()}] test" // should return true

Should return false (Not true)

share|improve this question
    
the last statement is redundant, a simple check if the value is !== 0 would be adequate. – Ryan McCullagh 7 hours ago
    
Corrected! thank you @RyanMcCullagh – TechnoCorner 7 hours ago
    
You have to keep track of the opening braces so you can make sure a closing one corresponds with the most recent still-open one. – Ryan 7 hours ago
8  
Instead of just counting braces, you may want to use a stack. Push left parentheses to the stack, when you encounter right parentheses you pop off the stack and compare. – Frxstrem 7 hours ago
up vote 11 down vote accepted

Use an array as a stack to keep track of unresolved opening braces:

function checkParanthesis(str){
  var stack=[];
  for(var i=0; i<str.length; i++){
    if(str[i] == "(" || str[i] == "{" || str[i] == "[")
      stack.push(str[i]);
    else if(str[i] == ")") {
        if(stack.pop() != "(") { return false; }
    }
    else if(str[i] == "}") {
        if(stack.pop() != "{") { return false; }
    }
    else if(str[i] == "]") {
        if(stack.pop() != "[") { return false; }
    } 
  }

  return !stack.length;
}

You can probably clean this up to be more readable, but basically:

  • Every time you find an opening brace, add it to the stack.
  • Every time you see a closing brace, pop the stack and see if the stack's top is a matching opening brace.
    • If it's not, you have a mismatch, so you can immediately return false.
  • If you make it to the end, you didn't spot any errors, return true if the stack is empty (i.e., stack.length is 0).

(Note I also changed your i in str loop since it will iterate over properties on String.prototype.)

One cleanup you could do (but I'm not sure if this makes the code more readable or not) would be to put the brace pairings in an object, with the closing character as the key and the corresponding opening character as the value. Then, see if the current character exists as a key in the object, and if so, pop the stack and see if the value for that key matches:

function checkParanthesis(str){
  var stack=[];
  var brace_pairings = { ")":"(", "}":"{", "]":"[" };
  for(var i=0; i<str.length; i++){
    if(str[i] == "(" || str[i] == "{" || str[i] == "[") {
      stack.push(str[i]);
    } else if(str[i] in brace_pairings) {
        if(stack.pop() != brace_pairings[str[i]]) { return false; }
    }
  }

  return !stack.length;
}
share|improve this answer
    
AMAZING! THANK YOU SO MUCH! – TechnoCorner 6 hours ago

Rather than a counter, you could use a stack, pushing a token onto the stack when an opening bracket is seen, and popping from the stack when the correct closing bracket is seen. If a closing bracket is encountered when a different type of bracket is at the top of the stack, or when the stack is empty, the string is unbalances.

Something like this (not polished and tested):

function checkParanthesis(str){
var stack = [];
var open;
for(var i in str){
  if(str[i] == "(" || str[i] == "{" || str[i] == "[") {
    stack.push(str[i]);
  }
  else if(str[i] == ")" || str[i] == "}" || str[i] == "]") {
    if ( stack.length == 0 ) {
       return false;
    }
    open = stack.pop();
    if (
       ( open == '(' && str[i] != ')' )
       || ( open == '[' && str[i] != ']' )
       || ( open == '{' && str[i] != '}' )
     ) {
       return false;
    }
  }
}

 if ( stack.length > 0 ) {
   return false;
 }

 return true;
}
share|improve this answer

Use a regex to get all the braces in a match() array...then remove each end of array testing each set

function checkParanthesis(str) {
  //hashmap to compare open/close braces
  var closers = {'[': ']','(': ')','{': '}'};
  // create braces array
  var parStack = str.match(/\(|\{|\[|\)|\}|\]/g) || [];

  if (parStack.length % 2 !== 0) {//must have even number
    return false;
  } else {
    while (parStack.length) {
      // check each end of array against each other.
      if (closers[parStack.shift()] !== parStack.pop()) {
        //mismatch , we're done
        return false;
      }
    }
    return true;
  }

}
console.log('no braces ', checkParanthesis("test"));
console.log('matched ', checkParanthesis("() test"));
console.log('mis matched ',checkParanthesis("[(]) abcd")); // should return false
console.log('matched ',checkParanthesis("[{()}] test"));

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.