首页 > 其他分享 >(转载)数据结构-02 中缀表达式转后缀表达式并计算值

(转载)数据结构-02 中缀表达式转后缀表达式并计算值

时间:2024-05-13 13:19:37浏览次数:12  
标签:02 出栈 中缀 tempChar 后缀 括号 myStack 表达式

1.图解中缀表达式转后缀表达式

通过 数据结构-01-图解后缀表达式值计算方式 我们了解到后缀表达式(例如:9 3 1 - 3 * + 10 2 /+)对计算机运算的方便,但是它却让我们这些人类十分的难受,因此我们需要在设计一个,中缀表达式转后缀表达式的程序来一劳永逸.

 

规则:依次遍历表达式,
1.如果是数字就添加到后缀表达式上(相反于数据结构-01-图解后缀表达式值计算方式
2.如果是符号就更栈顶Top符号比较优先级,低的输入会导致出栈(就是栈中高于或者等于都会全部出栈到后缀表达式上)
(符号的优先顺序为,乘除 > 加减 > 括号(括号的情况比较特殊,请结合代码和图解详细分析))

 

这里是一个 中缀表达式“9+(3-1)×3+10÷2”转化为后缀表达式 "9 3 1 - 3 * + 10 2 /+"的例子(我们使用空格将元素分开)

 

new 一个空栈
1.第一个是数字9,1.数字就添加到后缀表达式上

 2.第二个是+,判断栈顶的,只有低的输入才会导致出栈,因此这里将+加号入栈

 3.第三个是左括号 ( ,这里比较特殊,因为是左括号直接入栈

4.第四个是数字3,.数字就添加到后缀表达式上

 5.第五个是减号, 我们需要判断栈顶的符号,左括号的优先级是最小的,这里直接将减号入栈

 6.第六个是1,.数字就添加到后缀表达式上

 

7.第七-个是右括号,括号是优先级最低的,特殊,我们直接找到左括号,将括号中的东西减号(-)出栈

 8.第八个是乘法,判断符号优先级高于加法,因为只有低级输入才会导致出栈,这里直接入栈

 9.第九个是 3,数字直接输出到后缀表达式中

 10.第十个是 +,低级输入会导致出栈(这里的+号的等级小于 * 等于 + ,所以栈中的 * 和 +好都会出栈,然后第十个加号入栈)

 11.第十一个是 10,数字直接全部输出到后缀表达式(大家请这里思考一个问题:像10这样的2位数或者多位数我们如何遍历得到的是一个元素 10,而不是2个元素 1,0 呢?(后面的代码将会实现这个功能))

 12.第十二个是除 / ,符号比较优先级 ,除法的优先级高于加法,只有低输入才会导致出栈,-所以这里直接入栈

 13.第十三 是 2,数字直接输出到后缀表达式中,循环结束

 14.循环结束后将栈中所有的元素依次出栈,-添加到后缀表达式后面。程序结束

 

2.代码

如果你不能很好的理解这个代码,建议画出
1.后缀表达式的计算方法-图解
2.图解中缀表达式转后缀表达式

java

/**
 * @author 嘉文
 */
public class InfixToPostfix {
    public String infixToPostfix(String infix) {
        //init stack
        MyStack myStack = new MyStack(infix.length());
        //postfix.
        StringBuilder postfix = new StringBuilder();
        int length = infix.length();
        for (int i = 0; i < length; i++) {
            char tempChar;
            char charAt = infix.charAt(i);
            switch (charAt) {
                //左括号直接入栈,不用过多解释
                case '(':
                    myStack.push(charAt);
                    break;
                //如果遇到 +-,低级会导致一次出栈.
                case '+':
                case '-':
                    //出栈
                    while (!myStack.isEmpty()) {
                        tempChar = myStack.pop();
                        if (tempChar == '(') {
                            myStack.push(tempChar);
                            break;
                        }
                        postfix.append(" ").append(tempChar);
                    }
                    myStack.push(charAt);
                    break;
                case '*':
                case '/':
                    while (!myStack.isEmpty()){
                        tempChar = myStack.pop();
                        if (tempChar == '('||tempChar == '+' ||tempChar == '-') {
                            myStack.push(tempChar);
                            break;
                        }
                        postfix.append(" ").append(tempChar);
                    }
                    myStack.push(charAt);
                    break;
                case ')':
                    while (!myStack.isEmpty()){
                        tempChar = myStack.pop();
                        if (tempChar != '('){
                            postfix.append(" ").append(tempChar);
                        }else {
                            break;
                        }
                    }
                    break;
                default:
                    postfix.append(" ").append(charAt);
                    //if length enough
                    if (i<length-1){
                        int j = i + 1;
                        char nextNumber = infix.charAt(j);
                        while ((nextNumber+"").matches("^[0-9]*")&&j<length){
                            postfix.append(nextNumber);
                            nextNumber = infix.charAt(++j);
                        }
                        i = j-1;
                    }
                    break;


            }
        }
        while (!myStack.isEmpty()) {
            postfix.append(" ").append(myStack.pop());
        }
        return postfix.toString().trim();
    }
    public int getValueOfInfix(String infix){
        String postfix = infixToPostfix(infix);
        String[] items = postfix.split(" ");
        MyStack myStack = new MyStack(items.length);
        int length = items.length;
        for (int i = 0; i < length; i++) {
            String tempItem = items[i];
            switch (tempItem){
                case "+":
                    char first = myStack.pop();
                    char second = myStack.pop();
                    int result = (int)second + (int)first;
                    myStack.push((char)result);
                    break;
                case "-":
                    char first2 = myStack.pop();
                    char second2 = myStack.pop();
                    int result2 = (int)second2 - (int)first2;
                    myStack.push((char)result2);
                    break;
                case "*":
                    char first3 = myStack.pop();
                    char second3 = myStack.pop();
                    int result3 = (int)second3 * (int)first3;
                    myStack.push((char)result3);
                    break;
                case "/":
                    char first4 = myStack.pop();
                    char second4 = myStack.pop();
                    int result4 = (int)second4 / (int)first4;
                    myStack.push((char)result4);
                    break;
                //if is number.
                default:
                    int charInt = Integer.parseInt(tempItem);
                    myStack.push((char)charInt);
                    break;
            }
        }
        return myStack.pop();
    }

    /**
     * 这是一个简单的栈实现
     */
    class MyStack {
        private char[] stackArray;
        private int topIndex ;

        public MyStack(int maxSize) {
            stackArray = new char[maxSize];
            topIndex = -1;
        }
        public void push(char newTopItem){
            stackArray[++topIndex] = newTopItem;
        }
        public char pop(){
            return stackArray[topIndex--];
        }
        public char peek(){
            return stackArray[topIndex];
        }
        public boolean isEmpty(){
            return topIndex<0;
        }
    }
}

  测试

    public static void main(String[] args) {
        int valueOfInfix = new InfixToPostfix().getValueOfInfix("9+(3-1)*3+10/2");
        System.out.println(valueOfInfix);
    }

  输出:
在这里插入图片描述
计算正确

 

 

转自:https://blog.csdn.net/jarvan5/article/details/109207355

标签:02,出栈,中缀,tempChar,后缀,括号,myStack,表达式
From: https://www.cnblogs.com/didiao233/p/18189014

相关文章

  • (转载)数据结构-01-图解后缀表达式值计算方式
    目录:数据结构-01-图解后缀表达式值计算方式数据结构-02图解中缀表达式转后缀表达式并计算值1.简介问题:我们平常使用的数学表达式大多数是“中缀表达式”例如:9+(3-1)×3+10÷2,对人比较友好,但是这个对计算机计算并不友好,因为计算机无法智能判断运算顺序的问题(比如说乘法加......
  • 运算符与表达式
    运算符与表达式Created:November29,202310:38PM运算符运算符释义+、-、*、/略**、//、%乘方、整除(向下取整至最接近的整数、余数<<、>>指的是二进制左右移&按位与按位与是针对二进制数的操作,指将两个二进制数的每一位都进行比较,如果两个相应的二进......
  • 软工计算1—Java篇1 20240513
    Java中的函数重载函数重载(FunctionOverloading)是面向对象编程中的一个概念,它允许在同一个类中定义多个同名函数,但这些函数的参数列表必须不同。参数列表的不同可以体现在参数的类型、数量或顺序上。函数重载使得程序设计更加灵活,可以针对不同的参数类型或数量提供不同的函数实现......
  • P9425 [蓝桥杯 2022 国 B] 2022
    一、题目描述将\(2022\)拆分成\(10\)个互不相同的正整数之和,有多少种方案?二、问题简析令\(dp[i][j]=\)\(i\)的\(j\)划分的方案数(满足互不相同的正整数)。有两种实现方式:\(dp[i][j]\)不含\(1\)在\(dp[i-j][j]\)的基础上,每个元素+1。有\(j\)个元素,每个元素+1,......
  • 2024广东大学生攻防大赛WP
    Misc猜一猜题目描述:你们想要的flag就在压缩包里面。压缩包文件名解密解压密码为a1478520然后修改flag.png文件头得到扫描二维码之后❀❁❀❇❀✼❀❂✿❆✿✽❁❀✿✾❂❅✿❄❂❉❀✿❂❆❀❃❀✿❂❆✿❀❁✾✻✿❁❁❀❁❂❊✻❂✿❈=花朵解密https://www.qq......
  • EXP练手:CVE-2022-22963从编写到调试排错
    写什么?之前在使用Spring相关工具时候发现其中漏洞利用模块CVE-2022-22963需要手动利用(2023年的笔记,现在不确认工具是否更新了)GitHub-AabyssZG/SpringBoot-Scan:针对SpringBoot的开源渗透框架,以及Spring相关高危漏洞利用工具于是尝试编写这个exp,对编程不熟悉的可以看看我的Go......
  • 了解GaussDB SQL中CASE表达式
    本文分享自华为云社区《GaussDBSQL基本语法示例-CASE表达式》,作者:Gauss松鼠会小助手2。一、前言SQL是用于访问和处理数据库的标准计算机语言。GaussDB支持SQL标准(默认支持SQL2、SQL3和SQL4的主要特性)。本系列将以《云数据库GaussDB—SQL参考》在线文档为主线进行介绍。二、CA......
  • 2022广东大学生攻防大赛WP
    MISC复合尝试导出http数据发现文件类型和文件名都被改过把pass.md改为pass.zip,发现打不开添加文件头解压得到Emklyusg=E2=80=82gni=E2=80=82bvvymlag=E2=80=82tsqic=E2=80=82colz=E2=80=82jx=moxvl=E2=80=82tiwhz=E2=80=82ebmee,=E2=80=82Zhjeoig=E2=80=82Krpvpi-Zgvlyv......
  • pytest 学习 - 02 失败重新运行
    前言测试失败后要重新运行n次,要在重新运行之间添加延迟时间,间隔n秒再运行安装:pipinstallpytest-rerunfailures案例importpytestclassTestDemo:deftest_a(self):print("失败用例")assert1==2deftest_b(self):print("成功用......
  • 力扣1553 2024.5.13
    原题网址:此处为链接个人难度评价:1700分析:虽然不知道为什么贪心不对,但总之贪心不对。数据如此大也难以DP,那么只有搜索了。显然有一眼可得的搜索记忆化:记忆当只剩下k个果时还需要几天。值得一提的是,本代码实际上可能并不是一个正解代码,其可能无法在整数域上保证所有答案正确,但在......