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

举报
王小贰 发表于 2021/01/28 17:22:33 2021/01/28
【摘要】 使用中缀表达式基于栈实现一个简易的中缀表达式。实现思路:先对其判断字符str.charAt(i)是数字还是运算符,如果是数字直接入数栈,如果是运算符先判断是否栈空,栈空则直接入栈,栈不为空则判断当前运算符优先级和栈顶运算符优先级比较,当前运算符优先小于等于栈顶运算符,出两个数字栈,一个字符栈并做运算,将运算结果入栈,并将当前运算符入栈。依次遍历完字符。最后判断字符栈是否为空,为空直接出数字栈...

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

实现思路:先对其判断字符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;
    }


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。