java实现整数的四则运算,不包括小数和括号

// 枚举, 对应加减乘除
public enum OperatorEum {
    ADD("+"),
    SUBSTRACT("-"),
    MULTIPY("*"),
    DIVIDE("/");

    private String operatorSign;

    private OperatorEum(String operatorSign) {
        this.operatorSign = operatorSign;
    }

    public String getOperatorSign(){
        return operatorSign;
    }
    public static OperatorEum findOperatorEnum(String operatorSign) {
        for(OperatorEum value : values()) {
            if(value.getOperatorSign().equals(operatorSign)) {
                return value;
            }
        }
        return null;
    }
}

 



import java.util.Arrays;

// 定义一个栈,用来保存用于计算的数字和加减乘除符号
// 主要提供pop, peek, empty, size方法
public class CustomStack<T> {

    private int capacity;

    private int size = 0;

    private static int MAX = 16;

    private Object[] dataArr;

    public CustomStack() {
        this.capacity = MAX;
        dataArr = new Object[this.capacity];
    }

    public CustomStack(int capacity) {
        this.capacity = capacity;
        dataArr = new Object[this.capacity];
    }

    public boolean push(T data) {
        if(dataArr.length == size){
            return false;
        }
        dataArr[size++] = data;
        return true;
    }

    public T pop() {
        T data = (T)dataArr[--size];
        dataArr[size] = null;
        return data;
    }

    public T peek(){
        return (T)dataArr[size-1];
    }

    public boolean empty(){
        return size == 0;
    }

    public int size() { return size;}

    @Override
    public String toString() {
        return "CustomStack{" +
                "dataArr=" + Arrays.toString(dataArr) +
                '}';
    }

    public static void main(String[] args) {


    }
}

 

package test.stack;

import java.util.ArrayList;
import java.util.List;


public class CustomMath {
    // 保存在计算过程要用于计算的数字和临时计算结果
    private CustomStack<Integer> numberStack;
    // 保存在计算过程中要用于计算的运算符号
    private CustomStack<OperatorEum> operatorStack;

    // 按顺序保存数学式子中所有的数字
    private List<Integer> numberList;
    // 按顺序保存数学式子中所有的运算符号
    private List<OperatorEum> operatorEumList;

    public CustomMath(){
        numberStack = new CustomStack<>(10);
        operatorStack = new CustomStack<>(10);
        numberList = new ArrayList<>();
        operatorEumList = new ArrayList<>();
    }

    // 正式进行计算
    public Integer calculate(String mathExpression) throws Exception {
        System.out.println("mathExpression: "+mathExpression);
        Integer result = 0;
        if(checkExpression()){
            extractNumberAndOperatorToList(mathExpression);
            int numberSize = numberList.size();
            numberStack.push(numberList.get(0));
            for(int i=1; i<numberSize; i++){
                Integer number = numberList.get(i);
                int j=i-1;

                OperatorEum operatorEum = operatorEumList.get(j);
                if(operatorStack.size() == 0){
                    numberStack.push(number);
                    operatorStack.push(operatorEum);
                }else{
                    OperatorEum storedOperatorEum = operatorStack.peek();
                    if(storedOperatorEum.equals(operatorEum)){
                        Integer number1 = numberStack.pop();
                        Integer number2 = numberStack.pop();
                        result = calculate(number2, number1, operatorStack.pop());
                        numberStack.push(result);
                        numberStack.push(number);
                        operatorStack.push(operatorEum);
                    }else {
                        boolean superior = isSuperiorToStackOperator(storedOperatorEum, operatorEum);
                        if (superior) {
                            result = calculate(numberStack.pop(), number, operatorEum);
                            numberStack.push(result);
                        } else {
                            Integer number1 = numberStack.pop();
                            Integer number2 = numberStack.pop();
                            result = calculate(number2, number1, operatorStack.pop());
                            numberStack.push(result);
                            numberStack.push(number);
                            operatorStack.push(operatorEum);
                        }
                    }
                }
            }
        }else{
           throw new Exception("Illegal math expression");
        }
        while (numberStack.size() > 1){
            Integer number1 = numberStack.pop();
            Integer number2 = numberStack.pop();
            result = calculate(number2,number1, operatorStack.pop());
            numberStack.push(result);
        }
        return numberStack.pop();
    }

    // 具体的某种计算, 思路 number1 运算符号 number2, 两个参数的位置很重要,决定了
    // 在计算式了中的位置,直接影响计算结果,比如3-2与2-3,
    private Integer calculate(Integer number1, Integer number2, OperatorEum operatorEum){
        Integer result = 0;
        switch (operatorEum) {
            case ADD:
                result = number1+number2;
                break;
            case SUBSTRACT:
                result =  number1-number2;
                break;
            case MULTIPY:
                result =  number1*number2;
                break;
            case DIVIDE:
                result =  number1/number2;
                break;
        }
        return result;
    }

    // 将数学式子中的数字和运算符号按顺序保存到对应的List中
    private void extractNumberAndOperatorToList(String mathExpression){

        String numberStr = "";
        int length = mathExpression.length();
        for(int i=0; i<length; i++){
            char ch = mathExpression.charAt(i);
            OperatorEum operatorEum = OperatorEum.findOperatorEnum(String.valueOf(ch));
            if(operatorEum == null) {
                numberStr += ch;
            }else{
                this.numberList.add(Integer.valueOf(numberStr));
                numberStr = "";
                this.operatorEumList.add(operatorEum);
            }
        }
        this.numberList.add(Integer.valueOf(numberStr));
    }
    // 一般性的校验,检查一下输入的数学式子是否合未能
    private boolean checkExpression(){
        return true;
    }
    // 比较后一个运算符号的级别是否高于前一个运算符号,参数的位置很重要,
    // 前一个运算符号要作为第一个参数, 后一个运算符号要作为第二个参数
    private boolean isSuperiorToStackOperator(OperatorEum operatorEum1, OperatorEum operatorEum2){
        String stackOperator = operatorEum1.getOperatorSign();
        String operator = operatorEum2.getOperatorSign();
        boolean highPriority = operator.equals("*") || operator.equals("/");
        boolean lowPriority = stackOperator.equals("+") || stackOperator.equals("-");
        return highPriority && lowPriority;
    }

    // 进行测试
    public static void main(String[] args) {
        String expression = "0-1/1+2*2/2-1";  //
        CustomMath customMath = new CustomMath();
        try {
            Integer result = customMath.calculate(expression);
            System.out.println(result);
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

    }
}

核心思路讲解:

1. numberStack中只保存两个数字, operatorStack中只保存一个运算符号,这样两个栈中数据合起来就是一个完整的数学表达式: a+b,两个栈中的数据一直维持这种状态。  2.初次入栈。在第一次执行numberList的遍历前,先在numberStack中放入一个数字numberStack.push(numberList.get(0)),然后从1开始遍历。经过下面步骤,两个栈中的数据满足了第1点要求。

if(operatorStack.size() == 0){
    numberStack.push(number);
    operatorStack.push(operatorEum);
} 

3. 遍历计算及入栈讲解,看代码按思路分析。

// storedOperatorEum为符号栈中保存的运算符号, operatorEum为从符号list取出的运算符号
// number是从数字list中取出的数字,将用来计算或是入栈
OperatorEum storedOperatorEum = operatorStack.peek();
if(storedOperatorEum.equals(operatorEum)){
//如果运算符号相同,先将栈中数字和运算符号弹出并进行计算,将计算结果入栈保存,再将number入栈保存,
// 将operatorEum入栈保存
    Integer number1 = numberStack.pop();
    Integer number2 = numberStack.pop();
// 此处要注意,一定是第二次弹出的数字作为第一个运算数字,第一次弹出的数字作为第二个运算数字
// 因为3-2与2-3的结果就完全不同
    result = calculate(number2, number1, operatorStack.pop());
    numberStack.push(result);
    numberStack.push(number);
    operatorStack.push(operatorEum);
}else {
    boolean superior = isSuperiorToStackOperator(storedOperatorEum, operatorEum);
    if (superior) {
        // operatorEum的级别高于栈中运算符号的级别,就要数字栈中顶元素与number进行运算
// 将计算结果入栈。 要注意的是数字栈中的顶元素要作为第一个运算数字, number是作为第二个
// 此时,operatorEum与number都完成了计算,所以不需要入栈了
        result = calculate(numberStack.pop(), number, operatorEum);
        numberStack.push(result);
    } else {
// 如果operatorEum的级别与栈中运算符号的级别相等,则将栈中数字和运算符号弹出并进行计算,将计算// 结果入栈保存。
// 然后number与operatorEum要进行入栈
        Integer number1 = numberStack.pop();
        Integer number2 = numberStack.pop();
        result = calculate(number2, number1, operatorStack.pop());
        numberStack.push(result);
        numberStack.push(number);
        operatorStack.push(operatorEum);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值