[JAVA]使用棧(Stack)模擬算式計算器

使用棧(Stack)模擬算式計算器

public class Test {

  public static void main(String[] args) {
    String expression = "123-2*6-2";
    ArrayStack numStack = new ArrayStack(10);
    ArrayStack operStack = new ArrayStack(10);
    // loop at the position
    int index = 0;
    char ch = ' ';
    int num1 = 0;
    int num2 = 0;
    int operator = 0;
    int res = 0;

    // when num is not only a digit, then appends nums and gethers here
    String appendNum = "";

    // loop every char of expression
    do {
      ch = expression.substring(index, index + 1).charAt(0);
      if (ArrayStack.isOperator(ch)) {

        if (!operStack.isEmpty() && ArrayStack.priority(ch) <= ArrayStack.priority(operStack.peek())) {
          // current operator priority is less than the top of operStack
          // pop two nums, one operator to calculate
          num1 = numStack.pop();
          num2 = numStack.pop();
          operator = operStack.pop();
          res = ArrayStack.calc(num1, num2, operator);
          // push res to numStack
          numStack.push(res);
          // push current operator to operStack
          operStack.push(ch);
        } else {
          // current operator priority is more than the top of operStack
          // push operator to operStack directly
          operStack.push(ch);
        }

      } else {
        // char is number
        // char'3' == int 51 : numStack.push(ch - 48);
        // stores current num first
        appendNum += ch;

        if (index < expression.length() - 1) {

          // next to current num is operator, then num can push to numStack
          if(ArrayStack.isOperator(expression.substring(index + 1, index + 2).charAt(0))) {

            numStack.push(Integer.parseInt(appendNum));
            // Empty appendNum after push to numStack
            appendNum = "";
          } else if (ArrayStack.isSubtraction(expression.substring(index + 1, index + 2).charAt(0))) {
            numStack.push(Integer.parseInt(appendNum));
            // Empty appendNum after push to numStack
            appendNum = "";
            if (!operStack.isEmpty() && ArrayStack.priority('+') <= ArrayStack.priority(operStack.peek())) {
              num1 = numStack.pop();
              num2 = numStack.pop();
              operator = operStack.pop();
              res = ArrayStack.calc(num1, num2, operator);
              // push res to numStack
              numStack.push(res);
            }
            // push current operator to operStack
            operStack.push('+');

          }
        } else {
          // index == expression.length()
          numStack.push(Integer.parseInt(appendNum));
        }
      }
      index++;
    } while (index < expression.length());

    // loop until operStack is Empty, it meant it's finished
    do {
      // pop two nums and one operator to calculate
      num1 = numStack.pop();
      num2 = numStack.pop();
      operator = operStack.pop();
      res = ArrayStack.calc(num1, num2, operator);
      // push res to numStack
      numStack.push(res);
    } while (!operStack.isEmpty());

    // after the lastest loop, the number left in numStack is res
    System.out.printf("表達式%s=%d\n", expression, numStack.pop());
  }
}

// imitate stack by array
class ArrayStack {
  private int stackSize;
  private int[] stack;
  private int top;

  public ArrayStack(int stackSize) {
    this.stackSize = stackSize;
    this.stack = new int[stackSize];
    this.top = -1;
  }

  /**
   * verify expression char is operator or not?
   * @param ch
   * @return
   */
  public static boolean isSubtraction(char ch) {
    return ch == '-';
  }

  public static boolean isOperator(char ch) {
    return ch == '+' || ch == '*' || ch == '/';
  }

  /**
   * calculate
   * addition/ multiplication/ division
   * @param num1
   * @param num2
   * @param oper
   * @return
   */
  public static int calc(int num1, int num2, int oper) {
    int res = 0;
    if (oper == '+') {
      res = num1 + num2;
    } else if (oper == '*') {
      res = num1 * num2;
    } else if (oper == '/') {
      res = num2 / num1;
    }
    return res;
  }

  /**
   * get operator's priority number
   * @param ch
   * @return
   */
  public static int priority(int ch) {
    int priority = 0;
    if (ch == '*' || ch == '/') {
      priority = 1;
    } else if (ch == '+') {
      priority = 0;
    }
    return priority;
  }

  /**
   * get top of operStack
   * @return
   */
  public int peek() {
    return stack[top];
  }
  /**
   * check stack is empty?
   * @return
   */
  public boolean isEmpty() {
    return top == -1;
  }

  /**
   * check stack is full?
   * @return
   */
  public boolean isFull() {
    return top == stackSize - 1;
  }

  /**
   * push value to the top of stack
   * @param value
   */
  public void push(int value) {
    if (isFull()) {
      System.out.println("棧滿~~");
      return;
    }
    top++;
    stack[top] = value;
  }

  /**
   * get out the top of stack value
   * @return
   */
  public int pop() {
    if (isEmpty()) {
      throw new RuntimeException("棧空,沒有資料");
    }
    int value = stack[top];
    top--;
    return value;
  }

  /**
   * loop stack from the top
   */
  public void loopStack() {
    if (isEmpty()) {
      System.out.println("棧空,沒有資料");
      return;
    }
    for (int i = top; i >= 0; i--) {
      System.out.printf("stack[%d]=%d\n", i, stack[i]);
    }
  }
}

如有敘述錯誤,還請不吝嗇留言指教,thanks!