中缀表达式转后缀表达式实现逆波兰表达式计算


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

/**
 * 后缀表达式适合计算式进行计算,但是我们需要将 中缀表达式转成 后缀表达式
 * 1、初始化两个栈:运算符栈s1和存储中间结果的栈s2;
 * 2、从左至右扫描中缀表达式;
 * 3、遇到操作数时,将其压s2
 * 4、遇到运算符时,比较其与s1栈顶运算符的优先级:
 * (1)如果s1为空,或者栈顶运算符为左括号“(”,则直接将此运算符入栈;
 * (2)若优先级比栈顶运算符高,也将运算符压入s1
 * (3)否则,将s1栈顶的运算符弹出并压入s2中,然后再次与s1中的栈顶元素进行比较,直到当前运算符比栈顶运算符的优先级高或者栈空
 * 5、遇到括号时:
 * (1)如果是左括号,则直接压入s1
 * (2)如果是右括号,则依次弹出栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
 * 6、重复2-5,直到表达式的最右边
 * 7、将s1中剩余的运算符依次弹出并压入s2
 * 8、依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
 */
public class Calculator {

    public static void main(String[] args) {

//        String infixExpression = "1 * ( 2 + 3 - 4 * 5 ) * 6 - 7";   //测试结果为-97,正确
//        String infixExpression = "1 - 2 * 3 + 7";
        String infixExpression = "1 + ( ( 2 + 3 ) * 4 ) - 5";
        List<String> strings = getListString(infixExpression);
        System.out.println("中缀表达式转后缀表达式~~~~~~");
        ArrayList<String> list = infixToPostfix(strings);
        System.out.println(list);
        int result = calculate(list);
        System.out.println("计算结果 = " + result);
    }

    public static List<String> getListString(String expression) {
        String[] split = expression.split(" ");
        List<String> list = new ArrayList<>();
        for (String item : split) {
            list.add(item);
        }
        return list;
    }

    public static int calculate(List<String> list) {
        ArrayStack stack = new ArrayStack(10);
        for (String item : list) {
            if (item.matches("\\d+")) {
                stack.push(item);
            } else {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int res = 0;
                if ("+".equals(item)) {
                    res = num1 + num2;
                } else if ("-".equals(item)) {
                    res = num2 - num1;
                } else if ("*".equals(item)) {
                    res = num1 * num2;
                } else if ("/".equals(item)) {
                    res = num2 / num1;
                } else {
                    throw new RuntimeException("运算符号有误~");
                }
                stack.push("" + res);
            }
        }
        return Integer.parseInt(stack.peek());
    }

    /**
     * 中缀表达式转后缀表达式
     *
     * @param list 中缀表达式
     * @return
     */
    public static ArrayList<String> infixToPostfix(List<String> list) {
        ArrayList<String> numStack = new ArrayList();
        ArrayStack operatorStack = new ArrayStack(10);
        for (String item : list) {
            //如果是数字,直接加入栈numStack,否则,进行判断
            if (isOperator(item)) {
                //如果操作符栈为空或为左括号,直接加入
                if ("(".equals(item) || operatorStack.isEmpty()) {
                    operatorStack.push(item);
                    continue;
                }
                //如果是右括号,一直把符号栈的内容加入numStack,直到碰到左括号后,把左括号出栈
                if (")".equals(item)) {
                    while (!"(".equals(operatorStack.peek())) {
                        numStack.add(operatorStack.pop());
                    }
                    operatorStack.pop();
                    continue;
                }
                //如果当前符号优先级大于栈顶符号,直接入栈。否则,把栈顶符号加入numStack
                while (!operatorStack.isEmpty() && priority(item) <= priority(operatorStack.peek())) {
                    numStack.add(operatorStack.pop());
                }
                operatorStack.push(item);
            } else {
                numStack.add(item);
            }
        }
        //把符号栈中剩余的符号全部加入到numStack
        while (!operatorStack.isEmpty()) {
            numStack.add(operatorStack.pop());
        }
        return numStack;
    }

    public static boolean isOperator(String item) {
        return "+".equals(item) || "-".equals(item) || "*".equals(item) || "/".equals(item) || "(".equals(item) || ")".equals(item) || "=".equals(item);
    }

    public static int priority(String item) {
        if ("=".equals(item)) {
            return -1;
        } else if ("(".equals(item)) {
            return 0;
        } else if ("+".equals(item) || "-".equals(item)) {
            return 1;
        } else if ("*".equals(item) || "/".equals(item)) {
            return 2;
        } else if (")".equals(item)) {
            return 3;
        } else {
            throw new RuntimeException("运算符有误~");
        }
    }
}

class ArrayStack {
    public int maxSize;
    public String[] stack;
    public int top = -1;

    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new String[maxSize];
    }

    public boolean isFull() {
        return top == maxSize - 1;
    }

    public boolean isEmpty() {
        return top == -1;
    }

    public String peek() {
        if (isEmpty()) {
            throw new RuntimeException("栈空~");
        }
        return stack[top];
    }

    public void push(String value) {
        if (isFull()) {
            System.out.println("栈满");
            return;
        }
        stack[++top] = value;
    }

    public String pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈空~");
        }
        return stack[top--];
    }

    public int size() {
        return top + 1;
    }

    public void show() {
        if (isEmpty()) {
            System.out.println("栈空~");
            return;
        }
        for (int i = top; i >= 0; i--) {
            System.out.printf("stack[%s]=%s\n", i, stack[i]);
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值