用栈实现简易计算器

1,472 阅读2分钟

使用栈求得简单表达式的值

例:100+100/5-4等类似的式子,式中仅包含加减乘除,不包括小括号。所用栈由数组模拟实现。

实现思路

定义两个栈,一个用来存放数值,一个用来存放符号。

  • 使用while循环对整个式子进行扫描。
  • 当判断该字符为数字时:继续往后判断直到遇到符号时,对先前扫描过的字符保留有在字符串中的位置,进行截取并存储到数值栈中。
  • 当判断该字符为符号时,
    • 如果符号栈为空,则直接将该字符压入栈,继续扫描。
    • 如果符号栈不为空,则要判断目前的符号和栈顶符号的优先级,如果符号栈顶的符号优先级较高,则将其取出,并且取出数值栈中的前两个元素(这里注意取数值的顺序,以免运算错误)进行计算,然后将计算后的数值重新压入数值栈中,最后将目前扫描到的符号压入符号栈中。如果扫描到的符号优先级高于符号栈顶的符号,则直接将符号压入符号栈
  • 上述过程会持续到字符串扫描结束,此时如果符号栈不为空,则要从数值栈中取两个数值、符号栈中取出一个符号进行计算,重复该操作直到符号栈为空。此时数值栈中仅有一个元素为最终结果。

代码实现(java)

public class Stack_calu {
    public static void main(String[] args) {
        Stack stack_value = new Stack(10);
        Stack stack_symbol = new Stack(10);
        String express = "100+100/5-4";
        int index = 0;
        while ( index < express.length() ) {
            if (symbol(express.charAt(index))) {
                int end = index + 1;
                while (end < express.length() - 1 && symbol(express.charAt(end))) {
                    end++;
                }
                String value = express.substring(index, end);
                stack_value.push(value);
                index = end;
            } else {
                if (!stack_symbol.isEmpty()) {
                    if (priority(String.valueOf(express.charAt(index))) <= priority(stack_symbol.getTop())) {
                        String num2 = stack_value.pop();
                        String num1 = stack_value.pop();
                        String sym = stack_symbol.pop();
                        int num = makeCalculate(num2, num1, sym.charAt(0));
                        stack_value.push(String.valueOf(num));
                    }
                }
                stack_symbol.push(String.valueOf(express.charAt(index)));
                index++;
            }
        }
        while (!stack_symbol.isEmpty()) {
            String num2 = stack_value.pop();
            String num1 = stack_value.pop();
            String sym = stack_symbol.pop();
            int num = makeCalculate(num2, num1, sym.charAt(0));
            stack_value.push(String.valueOf(num));
        }
        System.out.printf("该表达式的结果是:%s",stack_value.getTop());
    }

    public static Boolean symbol(char ch) {
        return ch != '+' && ch != '-' && ch != '*' && ch != '/';
    }

    public static int priority(String ch) {
        int p = 0;
        switch (ch.charAt(0)) {
            case '+':
            case '-': {
                p = 1;
                break;
            }

            case '*':
            case '/': {
                p = 2;
                break;
            }
        }
        return p;
    }

    public static int makeCalculate (String num2, String num1 ,char ch) {
        int num = 0;
        switch (ch) {
            case '+':
                num = Integer.parseInt(num1) + Integer.parseInt(num2);
                break;
            case '-':
                num = Integer.parseInt(num1) - Integer.parseInt(num2);
                break;
            case '*':
                num = Integer.parseInt(num1) * Integer.parseInt(num2);
                break;
            case '/':
                num = Integer.parseInt(num1) / Integer.parseInt(num2);
                break;
        }
        return num;
    }
}

// 数组模拟栈
class Stack {
    private int maxSize;
    private int top = -1;
    private String [] stack;
    Stack (int maxSize) {
        this.maxSize = maxSize;
        this.stack = new String[maxSize];
    }

    // 判断栈为满
    public Boolean isFull () {
        return top == maxSize -1;
    }

    // 判断栈为空
    public Boolean isEmpty () {
        return top == -1;
    }

    // 入栈
    public void push (String  value) {
        if (!isFull()) {
            stack[++top] = value;
        } else {
            throw new RuntimeException("栈已满!");
        }
    }

    // 出栈
    public String pop () {
        if (!isEmpty()) {
            return stack[top--];
        } else {
            throw  new RuntimeException("栈为空!");
        }
    }

    // 获取栈顶元素
    public String getTop() {
        if (!isEmpty()) {
            return stack[top];
        } else {
            throw new RuntimeException("栈为空!");
        }
    }

    // 遍历栈
    public void check () {
        int index = 0;
        if (!isEmpty()) {
            System.out.println("从栈底到栈顶的元素依次为:");
            while (index <= top){
                System.out.printf("arr[%d] = %s\n",index,stack[index]);
                index++;
            }
        } else {
            throw new RuntimeException("栈中没有元素!");
        }
    }
}