栈及栈的应用

栈及栈的应用

  • stack:称做栈或堆叠,其特殊之处只容许在链表或数组的一端(堆栈顶端)插入(push)数据,输出数据(pop)
  • 其特色是先进后出
  • image

栈的实现

<!--链表实现-->
import LinkedList from '../linked-list/LinkedList';

export default class Stack {
  constructor() {
    this.linkedList = new LinkedList();
  }

  /**
   * @return {boolean}
   */
  isEmpty() {
    return !this.linkedList.tail;
  }

  /**
   * @return {*}
   */
  peek() {
    if (!this.isEmpty()) {
      return null;
    }
    return this.linkedList.tail.value;
  }

  /**
   * @param {*} value
   */
  push(value) {
    this.linkedList.append(value);
  }

  /**
   * @return {*}
   */
  pop() {
    const tailNode = this.linkedList.deleteTail();
    return tailNode ? tailNode.value : null;
  }

  /**
   * @return {*[]}
   */
  toArray() {
    return this.linkedList
      .toArray()
      .map(linkedListNode => linkedListNode.value)
      .reverse();
  }

  /**
   * @param {function} [callback]
   * @return {string}
   */
  toString(callback) {
    return this.linkedList.toString(callback);
  }
}

复制代码

应用

  1. 简单的四则元算
import Stack from './Stack';
export default class InToPost {
  constructor() {
    this.theStack = new Stack();
    this.output = [];
  }

  /**
   * 转换为后缀表达式
   */
  doTrans(str) {
    this.output = [];
    for (let i = 0, len = str.length; i < len; i++) {
      const ch = str.charAt(i);
      switch (ch) {
        case '+':
        case '-':
          this.getOper(ch, 1);
          break;
        case '*':
        case '/':
          this.getOper(ch, 2);
          break;
        case '(':
          this.theStack.push(ch);
          break;
        case ')':
          this.getParen();
          break;
        default:
          this.output.push(ch);
          break;
      }
    }
    while (!this.theStack.isEmpty()) {
      this.output.push(this.theStack.pop());
    }
    return this.output;
  }

  getOper(opThis, prec1) {
    while (!this.theStack.isEmpty()) {
      const opTop = this.theStack.pop();
      if (opTop === '(') {
        this.theStack.push(opTop);
        break;
      } else {
        let prec2 = 0;
        if (opTop === '+' || opTop === '-') {
          prec2 = 1;
        } else {
          prec2 = 2;
        }
        if (prec2 < prec1) {
          this.theStack.push(opTop);
          break;
        } else {
          this.output.push(opTop);
        }
      }
    }
    this.theStack.push(opThis);
  }

  getParen() {
    while (!this.theStack.isEmpty()) {
      const chx = this.theStack.pop();
      if (chx === '(') {
        break;
      } else {
        this.output.push(chx);
      }
    }
  }

  /**
   * 计算
   */
  calculation() {
    const caStack = new Stack();
    let num1 = 0;
    let num2 = 0;
    let ans = 0;
    let ch;
    for (let i = 0, len = this.output.length; i < len; i++) {
      ch = this.output[i];
      if (ch >= '0' && ch <= '9') {
        caStack.push(parseInt(ch));
      } else {
        num2 = caStack.pop();
        num1 = caStack.pop();
        switch (ch) {
          case '+':
            ans = num1 + num2;
            break;
          case '-':
            ans = num1 - num2;
            break;
          case '*':
            ans = num1 * num2;
            break;
          case '/':
            ans = num1 / num2;
            break;
          default:
            break;
        }
        caStack.push(ans);
      }
    }
    ans = caStack.pop();
    return ans;
  }
}

复制代码
  • 四则元算 目前仅支持10位之内计算
  1. 将中缀表达式3+2--->变为后缀表达式32+
  • (1)从左到右逐个扫描中缀表达式中的各项,若是到达末尾则跳转转到(6),不然根据(2)~(5)的描述进行操做;
  • (2)遇到操做数直接输出;
  • (3)遇到运算符(设为a),则和栈顶的操做符(设为b)比较优先级,若a小于等于b的优先级,则连续出栈输出,直到a大于b的优先级或b为(,a进栈;
  • (4)遇到(,进栈;
  • (5)遇到),则连续出栈输出,直到遇到左括弧(为止。其中,(出栈可是并不输出;
  • (6)输出栈中剩余的操做符。
  1. 计算后缀表达式的值,遇到数字压栈,遇到操做符取出数字计算结果,压栈,重复此过程至循环结束,取出数据即最后结果git

  2. 分割符匹配github

import Stack from './Stack';

export default class BracketChecker {
  constructor() {
    this.stack = new Stack();
  }

  check(str) {
    let isMatch = false;
    const map = new Map([
      ['{', '}'],
      ['[', ']'],
      ['(', ')']
    ]);
    const keys = [...map.keys()];
    const values = [...map.values()];
    for (let i = 0, len = str.length; i < len; i++) {
      const ch = str.charAt(i);
      if (keys.includes(ch)) {
        this.stack.push(ch);
      } else if (values.includes(ch)) {
        if (!this.stack.isEmpty()) {
          const chx = this.stack.pop();
          // 遇到)括号出栈,并从map里面找到)括号须要配对的(括号,相等则匹配成功
          const needKey = [...map.entries()].filter((el) => {
            return el[1] === ch;
          }).pop().shift();
          isMatch = needKey === chx;
        }
      }
    }
    return isMatch && this.stack.isEmpty();
  }
}

复制代码

参考连接

相关文章
相关标签/搜索