数据结构与算法之栈(简单计算器的实现)

//需要用到的栈类
public class StackDemo {
    private int top;
    private final int size;
    private final int[] stack;

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

    /**
     * 判断栈是否已满
     *
     * @return boolean
     */
    public boolean isFull() {
        return top == size - 1;
    }

    /**
     * 判断栈是否为空
     *
     * @return boolean
     */
    public boolean isEmpty() {
        return top == -1;
    }

    /**
     * 入栈
     *
     * @param element 元素
     */
    public void push(int element) {
        if (isFull()) {
            System.out.println("栈已满");
            return;
        }
        stack[++top] = element;
    }

    /**
     * 出栈
     *
     * @return element 元素
     */
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈已空");
        }
        return stack[top--];
    }

    /**
     * 查看栈顶元素
     *
     * @return 栈顶元素
     */
    public int peek() {
        if (isEmpty()) {
            throw new RuntimeException("栈为空");
        }
        return stack[top];
    }

    /**
     * 遍历栈
     */
    public void foreachStack() {
        if (isEmpty()) {
            System.out.println("栈为空");
            return;
        }
        for (int i = top; i > -1; i--) {
            System.out.printf("stack[%d] = %d\n", i, stack[i]);
        }
    }

}
/**
 * 简易计算器
 */
public class Calculator {

    public int getResult(String expr) {
        // 数字栈
        StackDemo digitalStack = new StackDemo(expr.length());
        // 操作符栈
        StackDemo operatorStack = new StackDemo(expr.length());
        for (int i = 0; i < expr.length(); ) {
            char ch = expr.charAt(i);
            // 判断是否是操作符
            if (isOperator(ch)) { // 字符是操作符
                // 判断是否是第一次入栈
                if (operatorStack.isEmpty()) { // 第一次入栈
                    operatorStack.push(ch); // char隐式转换成int
                } else { // 如果不是第一次入栈
                    // 当前操作符需要和栈顶操作符比较优先级
                    if (priority(ch) <= priority((char) operatorStack.peek())) { // 当前操作符的优先级小于或者等于栈顶操作符
                        // 把栈顶较大优先级的操作符取出
                        int operator = operatorStack.pop();
                        // 取出数字栈中的栈顶前两个数字
                        int digital1 = digitalStack.pop();
                        int digital2 = digitalStack.pop();
                        // 运算
                        int result = calculate(digital1, digital2, (char) operator);
                        // 运算完后将结果放回数字栈
                        digitalStack.push(result);
                        // 将当前的操作符放回操作符栈
                        operatorStack.push(ch);
                    } else { // 当前操作符的优先级比栈顶操作符大
                        // 直接入栈
                        operatorStack.push(ch);
                    }
                }
                i++;
            } else { // 字符是数字
                // 处理数字位数是多位的情况
                StringBuilder sb = new StringBuilder();
                sb.append(ch);
                int num = i + 1;
                for (int j = num; j <= expr.length(); j++) {
                    i = j;
                    if (j == expr.length()) {
                        break;
                    }
                    char cha = expr.charAt(j);
                    if (isOperator(cha)) {
                        break;
                    }
                    sb.append(cha);
                }
                // 数字正常入栈
                digitalStack.push(Integer.parseInt(sb.toString()));
            }
        }
        // 剩下的操作符的优先级都是一样的, 按顺序取操作符和数字计算即可
        while (!operatorStack.isEmpty()) {
            int operator = operatorStack.pop();
            // 取出数字栈中的栈顶前两个数字
            int digital1 = digitalStack.pop();
            int digital2 = digitalStack.pop();
            // 运算
            int result = calculate(digital1, digital2, (char) operator);
            // 运算完后将结果放回数字栈
            digitalStack.push(result);
        }
        return digitalStack.pop();
    }

    /**
     * 判断是否是操作符
     *
     * @param ch 字符
     * @return boolean
     */
    private boolean isOperator(char ch) {
        return ch == '+' || ch == '-' || ch == '*' || ch == '/';
    }

    /**
     * 比较字符的优先级
     *
     * @param ch 字符
     * @return 1 或者 0 或者 -1
     */
    private int priority(char ch) {
        if (ch == '*' || ch == '/') {
            return 1;
        } else if (ch == '+' || ch == '-') {
            return 0;
        } else {
            return -1;
        }
    }

    /**
     * 加减乘除四则运算
     *
     * @param num1     值1
     * @param num2     值2
     * @param operator 操作符
     * @return 结果
     */
    private int calculate(int num1, int num2, char operator) {
        int result = 0;
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num2 - num1;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                result = num2 / num1;
                break;
        }
        return result;
    }
}
/**
 * 测试类
 */
public class CalculatorTest {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        System.out.println("200 + 200 * 2 - 10 = " + calculator.getResult("200+200*2-10"));
    }
}
// 测试结果
200 + 200 * 2 - 10 = 590

分析:还是以画图为主吧,画图可以捋清思路,大家别嫌啰嗦哈:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

 

熬夜画完图感觉好累,博客上传完了休息去了,明天继续学习,大家晚安~~~~~

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值