zoukankan      html  css  js  c++  java
  • JS 检测括号边界匹配算法的简单实现

    话不多说,快上码!

    TODO:

    • 返回具体探测到的某个 item
    /**
     * @method checkBracketPairs
     * 解决的核心问题是: 括号边界的匹配,即检测起始和结束时的边界问题,每个起始必须匹配存在且正确的边界
     * @description 检测括号的算法
     *  1. 开始括号永远是前置(先)存在,然后才有结束括号
     *  2. 开始括号的标志位永远存在结束括号对应的标志位
     *  3. 条件自身即存在开始又存在结束,则不用处理类似(a)+(b)括号了自身
     * @example right:
     *  0. a || b
     *  1. (a && b) || c
     *  2. a || (b && c)
     *  3. ((a && b) || c) && d || e
     *  4. (((a && b) || c) && d) || e
     *  5. ((a && b) || c) && (d || e)
     * @example wrong:
     *  0. a) // or `(b`
     *  1. (a || b // or `a || b)`
     * @param {Array<{ leftBracket?: boolean, rightBracket?: boolean, [prop: string]: any }>} items
     * @returns {void|Error}
     */
    export const checkBracketPairs = (items) => {
      // 开始括号栈 => FILO 先入后出(push => 入, pop => 尾出)
      const leftStack = []
      // 结束括号队列 => FIFO 先入先出(push => 入, shift => 顶出)
      const rightQueue = []
    
      // 开始括号栈指针 flag
      let leftPointer = 0
      // 结束括号栈指针 flag
      let rightPointer = 0
    
      let i = 0
      const last = items.length
      const graphMap = new Map()
    
      if (items.length) {
        do {
          leftPointer = leftStack.length
          rightPointer = rightQueue.length
    
          const condition = items[i++]
    
          // leftBracket
          if (condition.leftBracket) {
            // 入栈并记录标志位
            leftPointer = leftStack.push(condition)
          }
    
          // rightBracket
          if (condition.rightBracket) {
            // 入栈并记录标志位
            rightPointer = rightQueue.push(condition)
    
            if (leftPointer) {
              // 左括号出栈,对应最新的 第一个右括号
              const l = leftStack.pop()
    
              // 右括号出列,对应其匹配的左括号
              const r = rightQueue.shift()
    
              if (l && r) {
                // 用图记录其位置 { l: r }
                graphMap.set(l, r)
              }
            } else {
              // 无左括号 => Error
              throw Error('无法找到匹配的左括号')
            }
          }
    
          // 依然存在右括号,而没有左括号
          if (!leftPointer && rightPointer) {
            throw Error('无法找到匹配的左括号')
          }
    
          // 依然存在左括号,而没有右括号
          if (leftPointer > rightPointer && i === last) {
            throw Error('无法找到匹配的右括号')
          }
        } while (i < last)
      }
    }
    
  • 相关阅读:
    继承
    接口
    匿名内部类
    抽象类和接口的区别
    多态
    重载和覆写的区别|this和super区别
    Visual C# 2008+SQL Server 2005 数据库与网络开发――2.2.1 变量
    Visual C# 2008+SQL Server 2005 数据库与网络开发――2.3.1 选择语句
    Visual C# 2008+SQL Server 2005 数据库与网络开发―― 2.5错误和异常处理
    Visual C# 2008+SQL Server 2005 数据库与网络开发―― 2.3 语句
  • 原文地址:https://www.cnblogs.com/givingwu/p/11726362.html
Copyright © 2011-2022 走看看