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

目录 :

1.二者区别:

1.中缀表达式:1 + 2 / 3         ( 3 * 2 + 1 ) / 5

2.后缀表达式:1 2 3 / +           3 2 * 1 + 5 /

划重点:后缀表达式将算术运算符的2个操作数放在该运算符之前,后缀表达式同时也表示了计算的顺序


2.转换的具体做法:

使用 来操作

  1. 首先创建一个操作符栈
  2. 将中缀表达式格式化,便于提取有效字符
  3. 扫描整个中缀表达式,按照下面的规则进行:
    1.数字直接输出
    2.左括号'('入栈
    3.遇到右括号')',将栈中所有的符号出栈输出直到遇到左括号'(',最后将左括号出栈
    4.其他符号(+、-、*、/),将栈中优先级大于等于当前符号的出栈, 直到遇到比当前符号优先级更低的符号或者'('或者栈空,将当前符号入栈。

  4. 最后,将栈中剩余的符号输出


3.计算的原理:

后缀表达式表示了计算的顺序,这里需要一个操作数栈

1.扫描后缀表达式
2.将数字入栈
3.遇到符号(+、-、*、/),弹出2个操作数,计算结果,然后将结果入栈
4.最后循环结束后,将栈中唯一的数字弹出即为结果

这里就不举列子了


4.举个例子:

( 3 * 2 + 1 ) / 5

  • ( 入栈
操作符栈:(
输出:
  • 3 输出
操作符栈:(
输出:3
  • *执行规则4,
操作符栈:( *
输出:3
  • 2 输出
操作符栈:( *
输出:3 2
  • +执行规则4
操作符栈:( +
输出:3 2 *
  • 1 输出
操作符栈:( +
输出:3 2 * 1
  • 遇到右括号,执行规则3
操作符栈:
输出:3 2 * 1 +
  • / 执行规则4
操作符栈:/
输出:3 2 * 1 +
  • 最后,将栈中剩余的符号输出
操作符栈:
输出:3 2 * 1 + /

5.代码:

PS:重点理解规则4的实现,我在这里卡了好久,虽然有点简单。还有就是一定注意格式化的具体做法。(⊙o⊙)…,这个代码敲了2晚上,继续加油吧!o(╥﹏╥)o改了4遍了,大哥大姐点个赞吧。

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

// 中缀表达式转为后缀表达式
public class InfixToPostfix {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("请输入一个中缀表达式:");
        String[] infix = formatInput(input.nextLine());// 输入格式化
        Stack<Character> operation = new Stack<>();// 操作符栈
        String postfix = "";// 后缀表达式,String
        for (String s : infix) {
            if (s.length() == 0)// 因为格式化后会多了无效的空格,在运算时忽略
                continue;
            // 其他符号(+、-、*、/),将栈中优先级大于等于当前符号的出栈, 直到遇到比当前符号优先级更低的符号或者'('或者栈空,将当前符号入栈。
            else if (s.charAt(0) == '+' || s.charAt(0) == '-' || s.charAt(0) == '*' || s.charAt(0) == '/') {
                while (!operation.isEmpty() && operation.peek() != '(') {
                    if (priorityIsBiggerOrTheSame(operation.peek() + "", s))// 将优先级大于等于自己的符号出栈输出
                        postfix += operation.pop() + " ";
                    else
                        break;// 如果遇到优先级小的符号,循环终止
                }
                operation.push(s.charAt(0));// 当前符号入栈
            }
            else if (s.charAt(0) == '(')// 左括号'('入栈
                operation.push(s.charAt(0));
            else if (s.charAt(0) == ')') {// 右括号')',将栈中的符号除了左括号'('全部出栈
                while (operation.peek() != '(')
                    postfix += operation.pop() + " ";
                operation.pop();
            }
            else// 最后,将数字输出,放在最后,可以不用判断字符串s为数字
                postfix += s + " ";
        }
        while (!operation.isEmpty())// 将剩余符号全部出栈输出
            postfix += operation.pop() + " ";
        System.out.println("后缀表达式:" + postfix);
        System.out.println("结果是:" + compute(postfix.split(" ")));
    }

    // 格式化中缀表达式输入,即在符号前后添加空格,便于后面的分隔操作
    public static String[] formatInput(String s) {
        String temp = "";
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '+' || c == '-' || c == '*' || c == '/')
                temp += " " + c + " ";
            else
                temp += c;// 数字不用加空格
        }
        return temp.split(" ");// 分割
    }

    // 计算后缀表达式的结果,将数字入栈,遇到符号,弹出2个数字运算,将结果入栈
    public static int compute(String[] postfix) {
        Stack<Integer> value = new Stack<>();
        for (String s : postfix) {
            char c = s.charAt(0);
            if (c == '+' || c == '-' || c == '*' || c == '/') {
                int v1 = value.pop();
                int v2 = value.pop();
                switch (c) {
                    case '+':
                        value.push(v2 + v1);
                        break;
                    case '-':
                        value.push(v2 - v1);
                        break;
                    case '*':
                        value.push(v2 * v1);
                        break;
                    case '/':
                        value.push(v2 / v1);
                        break;
                }
            }
            else
                value.push(Integer.parseInt(s));
        }
        return value.pop();
    }

    // 优先级判断,a是否大于b
    public static boolean priorityIsBiggerOrTheSame(String a, String b) {
        String s = "+- */";
        return (s.indexOf(a) - s.indexOf(b)) >= 2;
    }
}


5.结果截图:

截图1
截图2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值