栈_数组模拟栈_实现简单计算器

package com.zsx.structure.stack;

import java.util.HashMap;
import java.util.Map;

/**
 * 数组模拟栈
 * 栈实现简单计算器(+,-,×,/)功能
 */
public class SimpleCalculator {

    /**
     * 创建数学符号和优先级的对应关系
     */
    public static Map<Character, Integer> characterMap = new HashMap<>();

    //初始化~
    static {
        //        * × / 优先级最大
        //        - 优先级其次
        //        + 优先级最低
        // 先乘除
        // 后减   避免出现 1-2+2变成1—(2+2)
        // 最后加
        SimpleCalculator.characterMap.put('+', 1);
        SimpleCalculator.characterMap.put('-', 2);
        SimpleCalculator.characterMap.put('*', 3);
        SimpleCalculator.characterMap.put('×', 3);
        SimpleCalculator.characterMap.put('/', 3);
    }


    public static void main(String[] args) {

        //式子
        String formula = "1 + 3 - 2 * 2 / 2 + 92/92 - 1 + 5";

        //计算
        Integer result = SimpleCalculator.calcutator(formula);
        System.out.println(formula + "   =   " + result);

    }

    /**
     * 计算
     * <p>
     * ① 创建数字栈和符号栈用来存放对应的数字和符号
     * ② 遍历式子
     * * * * 数字:
     * * * * * ① 式子中的上一位非数字,则入栈
     * * * * * ② 式子中上一位是数字,则取出×10,再加后入栈   代表非个位数
     * * * * 符号:
     * * * * * ① 查看符号栈,优先级大于最后一个符号,则入栈
     * * * * * ② 查看符号栈,优先级小于最后一个符号,则取出最后一个符号和最后2个数字栈的数字,进行运算,运算结果放回数字栈,将当符号入符号栈
     * ③ 遍历最后的数字栈和符号栈,此时只剩 优先级最低的符号,不论顺序进行计算
     *
     * @param formula 式子
     */
    public static Integer calcutator(String formula) {
        // 数字栈 --用来存放数字
        Stack<Integer> number = new Stack<>(100);
        // 符号栈 --用来存放符号
        Stack<Character> character = new Stack<>(100);
        // 遍历式子中的每一个字符
        for (int i = 0; i < formula.length(); i++) {
            char c = formula.charAt(i);
            //是数字
            if (Character.isDigit(c)) {
                //上一位也是数字
                if (!number.isEmpty() && Character.isDigit(formula.charAt(i - 1))) {
                    //出栈
                    Integer last = number.pop();
                    //乘10再入栈
                    number.pull(last * 10 + (int) (formula.charAt(i)) - '0');
                } else {
                    //否则正常入栈
                    number.pull((int) (formula.charAt(i)) - '0');
                }
            }
            //是符号
            else if (characterMap.containsKey(c)) {
                if (!character.isEmpty()) {
                    //比较优先级 --.>如果当前符号的优先级小于之前符号的优先级
                    while (characterMap.get(character.getPop()) > characterMap.get(c)) {
                        //如果先前的优先级大
                        Integer num2 = number.pop();
                        Integer num1 = number.pop();
                        //取出先前的运算符进行运算
                        Integer res = SimpleCalculator.calcutator(num1, num2, character.pop());
                        //结果入数栈
                        number.pull(res);
                    }
                    //符号入符号栈
                    character.pull(formula.charAt(i));

                } else {
                    //符号入符号栈
                    character.pull(formula.charAt(i));
                }
            }
        }

        //最后遍历符号栈
        while (!character.isEmpty()) {
            // 数栈出栈
            Integer num2 = number.pop();
            Integer num1 = number.pop();
            Integer res = SimpleCalculator.calcutator(num1, num2, character.pop());
            //结果入数栈
            number.pull(res);
        }

        return number.getPop();
    }


    public static Integer calcutator(Integer num1, Integer num2, char charact) {

        switch (charact) {
            case '×':
            case '*':
                return num1 * num2;
            case '/':
                return num1 / num2;
            case '+':
                return num1 + num2;
            case '-':
                return num1 - num2;
            default:
                throw new RuntimeException("符号异常:" + charact);

        }

    }

}
package com.zsx.structure.stack;


class Stack<T> {

    //大小
    private int maxSize;
    //数据
    private T[] stack;
    //栈顶
    private int top = -1;

    public Stack(int maxSize) {
        this.maxSize = maxSize;
        stack = (T[]) new Object[maxSize];
    }

    /**
     * 判断满
     *
     * @return
     */
    public boolean isFull() {
        return top == maxSize - 1;
    }

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

    public void pull(T data) {

        if (this.isFull()) {
            System.out.println("满了");
            return;
        }
        top++;
        stack[top] = data;
    }

    public T pop() {
        if (this.isEmpty()) {
            throw new RuntimeException("空");
        }
        T value = stack[top];
        top--;
        return value;
    }

    public T getPop() {
        if (this.isEmpty()) {
            throw new RuntimeException("空");
        }
        return stack[top];
    }

    public void show() {
        System.out.println("________________________");
        if (!this.isEmpty()) {

            for (int i = this.top; i >= 0; i--) {
                System.out.println("第" + i + "个:" + this.stack[i]);
            }

        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值