Find the corresponding closing parenthesis Problem:


  "Sometimes (when I nest them (my parentheticals) too much (like this
  (and this))) they get confusing."


Write a function that, given a sentence like the one above, along with the position of an opening parenthesis, finds the corresponding closing parenthesis. For the above input string and position 10 the algorithm should output 76.

After some trial and error I am able to come up with an algorithm.



function findClosingBracketMatchIndex(str, pos) {
  let openBracketCount = 0;
  let givenBracketPosition = -1;
  let index = -1;
  for (let i = 0; i &lt; str.length; i++) {
    let char = str[i];
    if (char === '(') {
      openBracketCount++;
      if (i === pos) {
        givenBracketPosition = openBracketCount;
      }
    } else if (char === ')') {
      if (openBracketCount === givenBracketPosition) {
        index = i;
        break;
      }
      openBracketCount--;
    }
  }
  return index;
}

console.log(findClosingBracketMatchIndex('a (bc)', 2)); // 5
console.log(findClosingBracketMatchIndex('a (b ())', 2)); // 7
console.log(findClosingBracketMatchIndex('a (b ())', 5)); // 6
console.log(findClosingBracketMatchIndex('(a (b ()))', 0)); //9




Expert advice:

Apart from code review I would like to know if there are some tips to check the correctness of such algorithms, including off-by one error and conditions.
You might want to confirm that the character at the given position is indeed a (.

There is no reason to care about what appears before the given position.  You can start examining the string starting at pos + 1.  Once you have found the the position of the matching closing parenthesis, you can just return it right away; there is no need to ever set index.



function findClosingBracketMatchIndex(str, pos) {
  if (str[pos] != '(') {
    throw new Error("No '(' at index " + pos);
  }
  let depth = 1;
  for (let i = pos + 1; i &lt; str.length; i++) {
    switch (str[i]) {
    case '(':
      depth++;
      break;
    case ')':
      if (--depth == 0) {
        return i;
      }
      break;
    }
  }
  return -1;    // No matching closing parenthesis
}

console.log(findClosingBracketMatchIndex('a (bc)', 2)); // 5
console.log(findClosingBracketMatchIndex('a (b ())', 2)); // 7
console.log(findClosingBracketMatchIndex('a (b ())', 5)); // 6
console.log(findClosingBracketMatchIndex('(a (b ()))', 0)); //9