在字符串javascript中找到缺少的大括号

时间:2017-02-12 00:35:08

标签: javascript

我已经编写了检查“(”和“)”的括号的逻辑,但是当括号混合时似乎存在问题。这是因为我只是比较总括号数。

这就是我写的

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

问题:

  

但是如何检查多个括号元素? (){} []

例如,

输入:

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

应该返回false(Not true)

5 个答案:

答案 0 :(得分:22)

使用数组作为堆栈来跟踪未解析的开括号:

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

你可以清理它以使其更具可读性,但基本上是:

  • 每次找到左大括号时,请将其添加到堆栈中。
  • 每当你看到一个右大括号时,弹出堆栈,看看堆栈的顶部是否是一个匹配的左大括号。
    • 如果不匹配,则表示您不匹配,因此您可以立即返回false
  • 如果你到最后,你没有发现任何错误,如果堆栈为空(即truestack.length),则返回0

(注意我也更改了i in str循环,因为它将遍历String.prototype上的属性。)

你可以做的一次清理(但我不确定这是否使代码更具可读性)是将大括号配对放在一个对象中,关闭字符作为键和相应的开头字符作为价值。然后,查看当前字符是否作为对象的键in存在,如果是,则弹出堆栈并查看该键的值是否匹配:

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

答案 1 :(得分:6)

您可以使用堆栈,在看到开口括号时将令牌推入堆栈,而在看到正确的结束括号时从堆栈弹出,而不是计数器。如果在堆栈顶部有不同类型的括号时遇到关闭括号,或者当堆栈为空时,则该字符串是不平衡的。

像这样的东西(没有打磨和测试):

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

答案 2 :(得分:1)

使用正则表达式获取match()数组中的所有大括号...然后删除每组测试的每一端

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

答案 3 :(得分:0)

数组/堆栈/计数器方法从左到右读取字符串。另一种方法是从内到外工作。

function checkParanthesis(str){
  while ( str.indexOf('()')>=0 || str.indexOf('[]')>=0 || str.indexOf('{}')>=0 ) {
    str = str.replace('()','').replace('[]','').replace('{}','');
  }
  return str.length===0;
}

您可以使用正则表达式替换部件来执行全局替换并循环次数更少。缺点是你需要逃避一切:str.replace(/\(\)/g,'') et.c。

答案 4 :(得分:0)

自从我在 leetCode 上工作并找到您的问题以来,我发现这篇文章对问题写得很清楚,我对其进行了测试并在此处引用:

点击here! JavaScript 中的括号匹配问题

let isMatchingBrackets = function (str) {
    let stack = [];
    let map = {
        '(': ')',
        '[': ']',
        '{': '}'
    }

    for (let i = 0; i < str.length; i++) {

        // If character is an opening brace add it to a stack
        if (str[i] === '(' || str[i] === '{' || str[i] === '[' ) {
            stack.push(str[i]);
        }
        //  If that character is a closing brace, pop from the stack, which will also reduce the length of the stack each time a closing bracket is encountered.
        else {
            let last = stack.pop();

            //If the popped element from the stack, which is the last opening brace doesn’t match the corresponding closing brace in the map, then return false
            if (str[i] !== map[last]) {return false};
        }
    }
    // By the completion of the for loop after checking all the brackets of the str, at the end, if the stack is not empty then fail
        if (stack.length !== 0) {return false};

    return true;
}