zlx362211854 / daily-study

每日一个知识点总结,以issue的形式体现
10 stars 6 forks source link

22.校验代码括弧是否有效 #53

Open goldEli opened 5 years ago

goldEli commented 5 years ago

代码检测工具最要的一项检测就是括弧是否正确使用,包含括号 (,花括号 {,方括号 [。校验规则:是否成对使用。

const isValid = () => {
    // some code
}
isValid('()') // true
isValid('{([])}') // true
isValid('()[]{}') // true
isValid('([{}()])[]{}') // true
isValid('') // true
isValid(']') // false
isValid('([)]') // false
isValid('[') // false
zlx362211854 commented 5 years ago

最直白的做法:

const validate = code => {
  const map = {
    '(': 0,
    ')': 0,
    '[': 0,
    ']': 0,
    '{': 0,
    '}': 0
  };
  code = code.split('');
  for (let i = 0; i < code.length; i++) {
    if (map.hasOwnProperty(code[i])) {
      map[code[i]] += 1;
    }
  }
  return map['('] === map[')'] && map['['] === map[']'] && map['{'] === map['}']
};
console.log(validate('(()){}[]'));

但是只检测了括号是否成对,并没有检测括号的位置是否正确,比如: validate('({[]})')应该正确,validate('({[}])')这样的输入,就算符号是成对的,其实格式也不对。

goldEli commented 5 years ago

匹配成对出现的问题,用栈来解决。遇到左括弧压到栈中,遇到右括弧,与栈内最后一个左括弧匹配,如果匹配成功将该左括弧弹出。校验结束栈会被清空,即校验成功,反之则失败。

let isValid = str => {
  var stack = [];
  var o = {
    "(": 1,
    ")": -1,
    "[": 2,
    "]": -2,
    "{": 3,
    "}": -3
  };
  var all = str.split("");
  for (let i = 0; i < all.length; ++i) {
    let parenthesis = all[i];

    // 括弧的值大于0,则表示为左括弧
    if (o[parenthesis] > 0) {
      stack.push(o[parenthesis]);
      continue;
    }

    // 括弧的值小于0,则表示为右括弧,右括弧的值+左括弧等于0,则表示左右括弧匹配,即弹出,如果不等于0,直接校验失败
    if (o[parenthesis] < 0 && stack[stack.length - 1] + o[parenthesis] === 0) {
      stack.pop();
    } else {
      return false;
    }
  }
  // 栈清空,校验成功
  if (stack.length === 0) return true;
  // 反之校验失败
  return false;
};