中缀表达式转换为后缀表达式,并计算

**中缀表达式:**中缀表达式是一个通用的算术或逻辑公式表示方法

**后缀表达式:**也叫逆波兰式

关系:
中缀表达式:a+b
后缀表达式:a b +

我们对中缀表达式比较熟悉,对后缀表达式感觉难懂,但对于计算机来说,则后缀表达式比较好理解。

首先我们先看看后缀表达式如何运算:

1.a b +
假设有一个栈中存放数值;
从左到右我们如果遇见的是数值,则直接压入栈中,则栈中有a b 两个数值,当遇到运算符就从栈中取出两个数进行运算,将计算结果重新压入栈中,最后栈中的结构就是a+b;

2.ab+c*ab+e/-
同理:
1.-----> (a+b) c *ab+e/- a+b为一个数
2.-----> ( (a+b)*c) ab+e/= ( (a+b)*c)是一个数
3.----->( (a+b)*c) (a+b) e/- ( (a+b)*c)是一个数(a+b)是一个数
4.-----> ( (a+b)*c) (a+b)/e - ( (a+b)*c)是一个数(a+b)/e是一个数
5.-----> (a+b)*c-(a+b)/e 最终结果

代码实现

//计算结果;s中存储的为后缀表达式
        String[] s = postfix.split(" ");
        //定义一个栈用来存储数值
        Stack<Integer> numbers = new Stack<>();
        for (String temp : s){
            //如果是数值则直接入栈
            if (temp.matches("\\d+")){
                numbers.push(Integer.parseInt(temp));
            }else {
                //否则则将计算得到的值压入栈中
                int num1 = numbers.pop();
                int num2 =numbers.pop();
                int compute = Compute(num1, num2, temp);

                numbers.push(compute);

            }
        }

哪中缀表达式又是如何转换为后缀表达式的呢
我们用**(a+b)c-(a+b)/e* 举例说明
定义两个栈,一个用来存储表达式,一个用来存储运算符。
在这里插入图片描述
可以得到正确的后缀表达式

代码(没有考虑括号)

将中缀表达式先变为list然后变为后缀表达式


    //得到一个list中缀表达式

    public static ArrayList<String> getArrList(String exp){
        char[] expChar = exp.toCharArray();
        String s = "";
        ArrayList<String> infix = new ArrayList<>();//保存中序表达式
        for (int i = 0; i < expChar.length; i++) {
            if (expChar[i] == '+' || expChar[i] == '-' || expChar[i] == '*' || expChar[i] == '/') {
                infix.add(String.valueOf(expChar[i]));
            } else {
                s = s + (expChar[i] - '0');
                //判断是否到达末尾
                if (i + 1 < expChar.length) {
                    //如果待压入的数值的后一位不为运算符则拼接,否则直接压入
                    if (expChar[i + 1] == '+' || expChar[i + 1] == '-' || expChar[i + 1] == '*' || expChar[i + 1] == '/') {
                        infix.add(s);
                        s = "";

                    }
                } else {
                    infix.add(s);
                }
            }
        }
        return infix;
    }

    public static String infixTOPostfix(ArrayList<String> list){
        //定义两个栈 一个存表达式,一个用来存运算符
        Stack<String> oper = new Stack<>();
        Stack<String> expr = new Stack<>();

        //判断是运算符还是数值
        for (String a : list) {
            if (a.equals("+") || a.equals("-") || a.equals("*") || a.equals("/")) {
                //如果优先级高则直接入运算符栈
                while (true) {
                    if (oper.isEmpty() || priority(a) > priority(oper.peek())) {
                        oper.push(a);
                        break;
                        //否则将顶部的运算符取出压入表达式的栈
                    } else {
                        expr.push(oper.pop());
                    }
                }
                //数值直接压入
            } else {
                expr.push(a);
            }
        }
        //最后如果运算符栈中还有数值,则压入表达式栈
        while (!oper.isEmpty()){
            expr.push(oper.pop());
        }
        //用一个字符串 来结构表达式栈中的表达式,进行拼接
        StringBuilder s= new StringBuilder();

        while (!expr.isEmpty()){
            if (expr.size()!=1) {
                s.append(expr.pop()).append(" ");
            }else {
                s.append(expr.pop());
            }
        }

        //将刚拼接的表达式进行反转

        String[] str = s.toString().split(" ");

        StringBuilder temp = new StringBuilder();
        for (int i = str.length-1;i>=0;i--){
            if (i>0){
                temp.append(str[i]).append(" ");
            }else {
                temp.append(str[i]);
            }
        }


        return temp.toString();

    }

变为后缀表达式后,就可以直接计算。

下面为完整代码

package stack.postfixexpression;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

public class Calculate {
    public static void main(String[] args) {
        //接受一个表达式
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入表达式");
        String expression;
        expression = sc.nextLine();
        //将表达式用链表连接,将数值和运算符分开
        ArrayList<String> list =getArrList(expression);
        System.out.println(list);
        //将中缀表达式转换为后缀表达式
        System.out.println("----------");
        String postfix  =  infixTOPostfix(list);
        System.out.println(postfix);

        System.out.println("-----------");

        //计算结果;
        String[] s = postfix.split(" ");
        //定义一个栈用来存储数值
        Stack<Integer> numbers = new Stack<>();
        for (String temp : s){
            //如果是数值则直接入栈
            if (temp.matches("\\d+")){
                numbers.push(Integer.parseInt(temp));
            }else {
                //否则则将计算得到的值压入栈中
                int num1 = numbers.pop();
                int num2 =numbers.pop();
                int compute = Compute(num1, num2, temp);

                numbers.push(compute);

            }
        }

        System.out.println(numbers.pop());

    }

    //得到中缀表达式


    //得到一个list中缀表达式

    public static ArrayList<String> getArrList(String exp){
        char[] expChar = exp.toCharArray();
        String s = "";
        ArrayList<String> infix = new ArrayList<>();//保存中序表达式
        for (int i = 0; i < expChar.length; i++) {
            if (expChar[i] == '+' || expChar[i] == '-' || expChar[i] == '*' || expChar[i] == '/') {
                infix.add(String.valueOf(expChar[i]));
            } else {
                s = s + (expChar[i] - '0');
                //判断是否到达末尾
                if (i + 1 < expChar.length) {
                    //如果待压入的数值的后一位不为运算符则拼接,否则直接压入
                    if (expChar[i + 1] == '+' || expChar[i + 1] == '-' || expChar[i + 1] == '*' || expChar[i + 1] == '/') {
                        infix.add(s);
                        s = "";

                    }
                } else {
                    infix.add(s);
                }
            }
        }
        return infix;
    }

    public static String infixTOPostfix(ArrayList<String> list){
        //定义两个栈 一个存表达式,一个用来存运算符
        Stack<String> oper = new Stack<>();
        Stack<String> expr = new Stack<>();

        //判断是运算符还是数值
        for (String a : list) {
            if (a.equals("+") || a.equals("-") || a.equals("*") || a.equals("/")) {
                //如果优先级高则直接入运算符栈
                while (true) {
                    if (oper.isEmpty() || priority(a) > priority(oper.peek())) {
                        oper.push(a);
                        break;
                        //否则将顶部的运算符取出压入表达式的栈
                    } else {
                        expr.push(oper.pop());
                    }
                }
                //数值直接压入
            } else {
                expr.push(a);
            }
        }
        //最后如果运算符栈中还有数值,则压入表达式栈
        while (!oper.isEmpty()){
            expr.push(oper.pop());
        }
        //用一个字符串 来结构表达式栈中的表达式,进行拼接
        StringBuilder s= new StringBuilder();

        while (!expr.isEmpty()){
            if (expr.size()!=1) {
                s.append(expr.pop()).append(" ");
            }else {
                s.append(expr.pop());
            }
        }

        //将刚拼接的表达式进行反转

        String[] str = s.toString().split(" ");

        StringBuilder temp = new StringBuilder();
        for (int i = str.length-1;i>=0;i--){
            if (i>0){
                temp.append(str[i]).append(" ");
            }else {
                temp.append(str[i]);
            }
        }


        return temp.toString();

    }

    //自定义优先级

    public static int priority(String num) {
        if (num.equals("+") || num.equals("-")) {
            return 0;
        }
        if (num.equals("*") || num.equals("/")) {
            return 1;
        }
        throw new RuntimeException("表达式有误");
    }
    public static int Compute(int num1, int num2, String ope) {

        if (ope.equals("+")) {
            return num1  + num2;
        }
        if (ope.equals("-")) {
            return num2 - num1 ;
        }
        if (ope.equals("*")) {
            return num1*num2;
        }
        if (ope.equals("/")) {
            return num2  / num1 ;
        }

        throw new RuntimeException("计算有误");
    }




}

请大家多多指教!

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先需要将中缀表达式转换后缀表达式。可以使用一个操作符栈来辅助转换过程。从左到右扫描中缀表达式的每个字符,并根据优先级进行相应的操作。 具体步骤如下: 1. 定义一个操作符栈和一个后缀表达式字符串。 2. 从左到右扫描中缀表达式的每个字符: - 如果遇到数字,直接添加到后缀表达式字符串中。 - 如果遇到左括号,将其压入操作符栈。 - 如果遇到右括号,弹出操作符栈中的操作符,并将其添加到后缀表达式字符串中,直到遇到左括号为止,并将左括号从操作符栈中弹出。 - 如果遇到操作符,比较其与操作符栈栈顶操作符的优先级: - 如果该操作符优先级大于栈顶操作符优先级,将其压入操作符栈。 - 如果该操作符优先级小于等于栈顶操作符优先级,将栈顶操作符弹出,并将其添加到后缀表达式字符串中,直到栈顶操作符优先级小于该操作符,或者栈为空,然后将该操作符压入操作符栈。 3. 扫描完中缀表达式后,将操作符栈中的所有操作符依次弹出,并添加到后缀表达式字符串中。 4. 最后,后缀表达式字符串即为转换后的后缀表达式。 接下来是对后缀表达式进行求值的过程: 1. 定义一个数值栈。 2. 从左到右扫描后缀表达式的每个字符: - 如果遇到数字,将其转换成数值并压入数值栈。 - 如果遇到操作符,从数值栈中弹出两个数值,进行相应的操作,并将结果压入数值栈。 3. 扫描完后缀表达式后,数值栈中的唯一元素即为求值结果。 综上所述,将中缀表达式转换后缀表达式并求值的过程如上所述。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vivien_o.O

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值