1

I have below test cases in which i need to classify the correct expression in javascript.


(a) correct

((a)) correct

(a(b)) correct

(b) correct

(b  incorrect

You can see the last one is incorrect expression. How can we achieve this through javascript ?

Vickram
  • 187
  • 11
  • You mean, check balance of the parentheses? That's a well-known interview question: https://stackoverflow.com/questions/56656660/how-to-check-if-parentheses-are-balanced – ayanami Oct 03 '20 at 18:22
  • depending upon what `a` and `b` refers to your third expression can be incorrect. – Omkar76 Oct 03 '20 at 18:23
  • Yeah it's interview question and i was stunned. – Vickram Oct 03 '20 at 18:27

4 Answers4

0

A slightly edited answer from this link

function check(expr){
    const holder = []
    const openBrackets = ['(']
    const closedBrackets = [')']
    for (let letter of expr) { // loop trought all letters of expr
        if(openBrackets.includes(letter)){ // if its oppening bracket
            holder.push(letter)
        }else if(closedBrackets.includes(letter)){ // if its closing
            const openPair = openBrackets[closedBrackets.indexOf(letter)] // find his pair
            if(holder[holder.length - 1] === openPair){ // check if that pair is last element in array
                holder.splice(-1,1) //if so, remove it
            }else{ // if its not
                holder.push(letter)
                break // exit loop
            }
        }
    }
    if(holder.length === 0)
    {
      console.log("correct");
    }
    else{
      console.log("incorrect");
    }
}
check('(a)') /// give the string you want to check here
Paul Baiju
  • 419
  • 7
  • 20
0

You will need to use a simple stack to store the opening parenthesis. Here is a brief explanation:

  1. Convert the string into an array of characters
  2. Create an empty stack
  3. Iterate over each character:
    • if the character is not a parenthesis, continue to the next iteration
    • if it's an opening parenthesis, store it in the stack
    • if it's a closing parenthesis, then there are two possibilities:
      • if there are no corresponding opening parenthesis for it in the stack, then the string is not valid
      • if there is, then, pop the corresponding opposite parenthesis and continue normally

let t1 = '(a)', t2 = '((b))', t3 = '(a(b))', t4 = '(b';
const isValid = (str) => {
     let characters = str.split('');
     let stack = [];
     for(let i = 0; i < characters.length; i++){
          let c = characters[i];
          if(c !== '(' && c !== ')') 
               continue;
          else if(c === '(')
               stack.push(c);
          else if(c === ')'){
               if(stack.length==0)
                    return false;
               else
                    stack.pop();
          }
     }
     return stack.length==0;
}

console.log(isValid(t1));
console.log(isValid(t2));
console.log(isValid(t3));
console.log(isValid(t4));
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
0

If they want to check strings, then I would just loop over the string. I would have a variable (characterCount) that adds one for every '(' character and subtract one for every ')'. If the end result is 0, then it's correct formatting.

EDIT: I also need to check if characterCount is ever negative, which means that there is an incorrect formatting.


If it's an interview, ask them to clarify. Programmers that ask are more valuable than programmers that assume (and spend hours of valuable time coding wrong functionality).

function checkFormatting(str) {
  const END_CHARACTER_BEFORE_START_CHARACTER = CORRECT_FORMATTING = 0;
  let characterCount = CORRECT_FORMATTING;
  let startCharacter = '(';
  let endCharacter = ')';
  
  for(let i = 0; i < str.length; i++) {
    characterCount += Number(str[i] == startCharacter); // +1 if true
    characterCount -= Number(str[i] == endCharacter);   // -1 if false

    if (characterCount < END_CHARACTER_BEFORE_START_CHARACTER) { // EDIT
      console.log(str, false);
      return false;
    }
  }

  console.log(str, characterCount == CORRECT_FORMATTING);

  return characterCount == CORRECT_FORMATTING;
}

checkFormatting('(a)');    // true
checkFormatting('((a))');  // true
checkFormatting('(a(b))'); // true
checkFormatting('(b)');    // true
checkFormatting('(b');     // false
checkFormatting('))a((');  // false
Rickard Elimää
  • 7,107
  • 3
  • 14
  • 30
0

To handle other types of brackets - {}, [] and the ():

function matchBrackets(s) {
  let x = "";
  let c = [];
  let ok = true;
  for (let i = 0; i < s.length; i++) {
    x = s.substr(i, 1);
    switch (x) {
      case "{":
        c.unshift("}");
        break;
      case "[":
        c.unshift("]");
        break;
      case "(":
        c.unshift(")");
        break;
      case "}":
        if (c[0] == "}") {
          c.shift();
        } else {
          ok = false;
        }
        break;
      case "]":
        if (c[0] == "]") {
          c.shift();
        } else {
          ok = false;
        }
        break;
      case ")":
        if (c[0] == ")") {
          c.shift();
        } else {
          ok = false;
        }
        break;
    }
    if (!ok) {
      break;
    }
  }
  if (c.length > 0) {
    ok = false;
  }
  return ok;
} 

let tocheck = [];
tocheck.push("a(b][}c");
tocheck.push("a(bc");
tocheck.push("a)(bc");
tocheck.push("a(b)[c]{(d)}");
tocheck.push("(a)");
tocheck.push("((a))");
tocheck.push("(a(b))");
tocheck.push("(b)");
tocheck.push("(b");
tocheck.push("))a((");

for (let i = 0; i < tocheck.length; i++) {
  console.log(tocheck[i] + ": " + matchBrackets(tocheck[i]));
}

This works in a similar way to the others but ensures that a closing bracket of any type must match with the last opening bracket of the same type.

ATD
  • 1,344
  • 1
  • 4
  • 8