使用中缀表达式实现一个简易计算机

开学学算法的第5天

使用中缀表达式基于栈实现一个简易的中缀表达式。

实现思路:先对其判断字符str.charAt(i)是数字还是运算符,如果是数字直接入数栈,如果是运算符先判断是否栈空,栈空则直接入栈,栈不为空则判断当前运算符优先级和栈顶运算符优先级比较,当前运算符优先小于等于栈顶运算符,出两个数字栈,一个字符栈并做运算,将运算结果入栈,并将当前运算符入栈。依次遍历完字符。最后判断字符栈是否为空,为空直接出数字栈为最终结果,不为空则出数字栈两个元素,出运算符栈一个元素并计算然后将结果入数字栈,直到运算符栈为空。

图解:
在这里插入图片描述

class stack<E>{
    private E[] arr;
    private int size;

    public stack(int capacity){
        arr = (E[]) new Object[capacity];
    }

    //入栈
    public void push(E val){
        if (isFull()){
            ensureCapacity();
        }
        arr[size] = val;
        size = size+1;
    }

    //出栈
    public E pop(){
        //判空
        if (isEmpty()){
            throw new RuntimeException("空栈");
        }
        //出栈一次就要进行元素的移动
        E val = arr[this.size-1];
        this.size--;

        this.arr = Arrays.copyOf(this.arr,size);
        return val;
    }

    //判空
    public boolean isEmpty(){
        return this.size == 0;
    }

    //判满
    public boolean isFull(){
        return this.size == this.arr.length;
    }

    //扩容
    public void ensureCapacity(){
        if (size == arr.length){
            this.arr = Arrays.copyOf(arr, arr.length *2 + 1);
        }
    }

    //获取栈顶元素
    public E peek(){
        return this.arr[size-1];
    }
}

public class ComputerDemo {
    public static void main(String[] args) {
        stack<Integer> number = new stack<>(10);
        stack<Character> chars = new stack<>(10);
        String expression = "7*2*2-5+1-5+3-4";
        calculator(number,chars,expression);
    }
    //中缀
    public static void calculator(stack<Integer> number,stack<Character> chars,String expression){
        for (int i = 0; i < expression.length(); i++) {
            if (Character.isDigit(expression.charAt(i))){
                //表示当前字符为数字
                String s = String.valueOf(expression.charAt(i));
                int j = i+1;
                String tmp = new String();
                //这里出现70+2这种情况将数字拼接起来
                while (j < expression.length()){
                    if (Character.isDigit(expression.charAt(j))){
                        tmp+=expression.charAt(j);
                    }else {
                        break;
                    }
                    j++;
                }
                i = j -1;
                s += tmp;
                Integer value = new Integer(s);
                //将连续两个数字的字符拼接起来并入栈
                number.push(value);
            }else{
                //运算符
                if (chars.isEmpty()){
                    //字符栈为空直接入栈
                    chars.push(expression.charAt(i));
                }else{
                    int priority = priority(expression.charAt(i));
                    Character peek = chars.peek();
                    int peeks = priority(peek);
                    //将当前字符与栈中的字符作比较
                    if (priority <= peeks){
                        int num1 = number.pop();
                        int num2 = number.pop();
                        Character pop = chars.pop();
                        int compute = compute(num1, num2, pop);
                        //将计算结果入栈
                        number.push(compute);
                        //将当前运算符入栈
                        chars.push(expression.charAt(i));
                    }else {
                        chars.push(expression.charAt(i));
                    }
                }
            }
        }
        //需要对其符号栈做出判空处理  如果为空则直接打印number栈即可,否则继续计算
        while (!chars.isEmpty()){
            Character pop = chars.pop();
            Integer num1 = number.pop();
            Integer num2 = number.pop();
            int res = compute(num1, num2, pop);
            number.push(res);
        }

        System.out.println(number.pop());
    }

    //设置运算符的优先级,优先级越高数字值越大
    public static int priority(char oper){
        if (oper == '*' || oper == '/'){
            return 1;
        }else if (oper == '+' || oper == '-'){
            return 0;
        }else{
            return -1;
        }
    }


    //计算方法
    public static int compute(int num1,int num2,char oper){
        int res = 0;
        switch (oper){
            case '+':
                res = num1+num2;
                break;
            case '/':
                res = num2/num1;
                break;
            case '*':
                res = num1*num2;
                break;
            case '-':
                res = num2 - num1;
                break;
        }
        return res;
    }


}

在这里插入图片描述
点个赞呗~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值