中缀表达式转后缀表达式看完这一篇文章你就懂了

这篇具有很好参考价值的文章主要介绍了中缀表达式转后缀表达式看完这一篇文章你就懂了。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章目录

  • 一、什么是中缀表达式

  • 二、什么是后缀表达式

  • 三、后缀转中缀具体思路

  • 四、代码实现



一、什么是中缀表达式

中缀表达式就是我们常用的算术表达方式,例如(12+34)*5,运算符在两个数的中间,但是对于中缀表达式来说括号和加减乘除使得问题对于计算机非常复杂,为了有效的处理他们,波兰逻辑学家想到了一种不需要括号的后缀表达式,我们称之为逆波兰。

二、什么是中缀表达式

后缀表达式也称逆波兰式或逆波兰记法,它通过中缀表达式转换而来,没有括号,只有数字和运算符,运算符总在要计算的数字的后面,之所以叫后缀表达式 是因为所有的运算符号都要在数字后面出现才行。举个例子来说,假如中缀表达式是:(12+34)*5那么转换为后缀表达式就是:12 34 + 5 *


看到这里,你可能蒙圈了,我们先把中缀表达式计算出来,结果是230

此时此刻你一定想问,如何计算?其实很简单:

每次从左往右找到第一个运算符的位置,然后拿到前面两个位置的元素,跟这个运算符进行+-*/ 运算,运算完将运算符和这两个元素删掉,再将新算出来的元素添加到运算符前面的位置,每次都这样计算,当后缀表达式为空时,就可以得到最终的那个结果。

看到这里,你应该顿悟了吧,如果还不明白,后面我会给出代码,相信你会明白的。

三、后缀转中缀具体思路

接下来是思路:

第一步:定义两个栈,一个用来存储后缀表达式栈,一个用来存储中间的运算符栈。

第二步:写个循环,从左往右遍历中缀表达式。

第三步:在循环中处理数字和运算符即可

怎么处理呢?接下来就为大家讲解

  1. 如果遇到数字,代表他是要运算的值,直接入后缀表达式栈

  1. 如果遇到了运算符,可以分情况讨论,有以下情况

  • 当前栈为空,那就代表是第一个运算符,入栈即可

  • 当前栈不为空,当前运算符大于栈顶运算符,入栈即可,如果小于或等于当前运算符,直接将运算符栈弹至后缀表达式栈

  1. 遇到括号,也要分情况讨论,有以下情况

  • 左括号,直接入栈即可

  • 右括号,弹出运算符直至左括号为止(实际上就是把这个括号包含的所有运算符弹出)

  1. 还要注意一点:如果运算符当前栈顶是'(',那么下一个运算符无论是什么都要入栈

  1. 表达式遍历完后,把运算符栈剩下的弹至后缀表达式栈即可


四、代码实现

/*
中缀表达式转为后缀表达式具体思路:
1.定义两个栈,一个栈用来存储后缀表达式,一个栈用来存储中间的运算符
(括号,+,-,/,*这些)
2.如果遇到数字,直接入后缀表达式栈
3.如果遇到运算符了,分情况讨论:
第一种:括号,如果是左括号,直接入栈,如果是右括号,把栈顶的运算符
给到后缀表达式栈中即可
第二种:+,-,*,/,这些,如果遇到运算符优先级大于栈顶的运算符,直接入
栈,如果遇到不大于栈顶的优先级的运算符,直接出栈,然后再把当前运算
符入栈即可(tips:注意如果是运算符优先级相同,把栈顶运算符出栈即可)
4.重复操作即可
*/
#include <iostream>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
typedef double d;
using namespace std;
enum Operator   //运算符优先级
{
    //左括号     右括号        加     减       乘         除
    left_bracket=2,right_bracket=0,Add=0, Minus=0, Multiply=1,Div=1
};
int Get_Operator_size(char cc){ //根据符号返回对应的运算符优先级
    switch (cc) {
    case '+': return Add;
    case '-': return Minus;
    case '*':return Multiply;
    case '/':return Div;
    case '(':return left_bracket;
    case ')':return right_bracket;
    default: return -1;
    }
}
struct expression{ //后缀表达式数据
    string str;     //运算符或者要运算的数字
    expression(string str):str(str){}
    expression(){}
};
class Slove_expression{
public:
    Slove_expression(){}
    Slove_expression(string Expree):Expree(Expree){}
    inline void Set_Expression(string Expree) { this->Expree = Expree;}
    vector<expression> Get_Front_expression() {
        int p = 0;
        string temp;
        expression Next;
        while (p<Expree.size()) {
            if(Expree[p]>='0'  && Expree[p]<='9')
            temp.push_back(Expree[p]);   //保存数据
            if ((p>=1  && Get_Operator_size(Expree[p])!=-1 && Expree[p-1]>= '0' 
                && Expree[p - 1] <= '9')
                || p+1==Expree.size()) {  //处理最后一个整数式子
                //遇到运算符了 并且前面是数字 让数字入栈
                Next.str = temp;
                Stack.push(Next);    //如果是参与运算的数字 直接入栈
                temp.erase(temp.begin(),temp.end());  //将里面的数据删掉 防止重复
            }
            if (Get_Operator_size(Expree[p])!=-1 && (operation.empty() || 
             Get_Operator_size(Expree[p])>Get_Operator_size(operation.top().str[0])
            ||  operation.top().str[0]=='('))
                //如果运算符栈为空 直接将运算符入栈  或者运算符优先级大于顶栈运算符 入栈即可
            {
                //cout << Expree.substr(p, 1) << endl;
                Next.str = Expree.substr(p,1);  //将运算符切割出来
                operation.push(Next);          //运算符入栈
            }
            else if(Get_Operator_size(Expree[p])!=-1){  //运算符优先级一样 或者走到)运算符了
                if (Expree[p] == ')')   //右括号处理方式
                {
                    while(operation.top().str[0]!='('){
                        Stack.push(operation.top());
                        operation.pop();
                    }
                    operation.pop();
                }
                else {  //非右括号
                    Stack.push(operation.top());    //将运算符栈顶出栈
                    operation.pop();
                    Next.str = Expree.substr(p, 1);
                    operation.push(Next);
                }
            }
            p++;
        }
        while (!operation.empty()){  //将剩下的运算符入栈
            Stack.push(operation.top());
            operation.pop();
        }
        vector<expression> arr;
        while (!Stack.empty()){
            expression curr = Stack.top();
            arr.insert(arr.begin(),curr);
            Stack.pop();
            //cout << curr.str << '\t';
        }
        //cout << endl;
        return arr;
    }

private:
    stack<expression> Stack;    //后缀表达式栈
    stack<expression> operation;  //运算符栈
    string Expree;  //表达式
};
class Value{  //通过后缀表达式计算出具体的值
public:
    Value(){}
    Value(vector<expression> arr) :arr(arr){}
    inline void Set_Value_Arr(vector<expression> arr) { this->arr = arr; }
    d Two_Number_Value(d left,char cc,d right){
        switch (cc) {
        case '+': return left + right;
        case '-':return left - right;
        case '/':return left / right;
        case '*':return left * right;
        default:return -1;
        }
    }
    d Get_Value(){
        int p = 0;
        d two_Number;
        //加一个数据防止出现下标问题
        arr.push_back(expression(string("#")));
        while (1) {
            if (Get_Operator_size(arr[p].str[0]) != -1) {   //找到运算符了
                two_Number = Two_Number_Value(stod(arr[p - 2].str), arr[p].str[0],
                    stod(arr[p - 1].str));
                //cout << two_Number << endl;
                arr.erase(arr.begin()+p-2,arr.begin()+p+1);
                //cout << arr.size() << endl;
                if (arr.size()==1 && (*(arr.begin())).str[0] == '#')
                    break;
                arr.insert(arr.begin()+p-2, expression(to_string(two_Number)));
                p -= 2;
            }
            p++;
         }
        return two_Number;
    }
private:
    vector<expression> arr;
};
signed main() {
    string str;
    Slove_expression* solve = new Slove_expression;
    Value* value = new Value;
    while (1) {
        cout << "请输入表达式:";
        cin >> str;
        solve->Set_Expression(str);
        vector<expression> arr = solve->Get_Front_expression();
        value->Set_Value_Arr(arr);
        cout << "reslt:"<<value->Get_Value();
        cout << endl;
    }
    return 0;

}

总结:中缀表达式转后缀表达式实际上就是栈的运用,如果你不了解栈,建议了解完再来看本篇文章。文章来源地址https://www.toymoban.com/news/detail-715481.html

到了这里,关于中缀表达式转后缀表达式看完这一篇文章你就懂了的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】13:表达式转换(中缀表达式转成后缀表达式)

    从头到尾依次读取中缀表达式里的每个对象,对不同对象按照不同的情况处理。 如果遇到空格,跳过 如果遇到运算数字,直接输出 如果遇到左括号,压栈 如果遇到右括号,表示括号里的中缀表达式已经扫描完毕,将栈顶的运算符弹出并输出, 直至遇到左括号(左括号出栈

    2024年02月19日
    浏览(44)
  • 中缀表达式转后缀表达式,使用逆波兰计算。可以计算小数

    传递一个分开保存符号与数字的List即可:List SumNumber; 获取参数的构造方法如下: 要求的List保存数据的方式如下: 例如:1+2+3 然后使用 EvaluatePostfixExpressions 方法传递出一个保存好结果的String。

    2024年02月15日
    浏览(47)
  • Golang通过栈实现表达式运算(中缀表达式转后缀表达式解析语法)

    需求背景:将string表达式数组 [title == AUSU ( header == Wecome || brand != AC68U )] 解析并使用ES查询得到运算结果。 分析:带有括号的表达式,需要根据优先级解析,可将中缀表达式转换为后缀表达式,去除括号

    2024年02月14日
    浏览(43)
  • C++ 数据结构 栈 中缀表达式转后缀表达式并求值

    写在前面,这里用的是我自己写的Stack类,并非STL,实现方法为静态数组,但使用过程中的函数方法一样,无伤大雅。(完整code和Stack_static类赋在最后) 1.从左到右遍历 2.数,即参与运算数,直接放进后缀表达式之后 3.左括号 ,直接压入栈(因为括号的优先级最高,无需判断

    2024年02月03日
    浏览(40)
  • 【尚硅谷】数据结构和算法——前缀、中缀、后缀表达式规则

    跟着B站的尚硅谷学习数据结构与算法,语言为java,目前是第七个代码内容——前缀、中缀、后缀表达式 课程传送门:尚硅谷——前缀、中缀、后缀表达式 1)前缀表达式又称波兰式, 前缀表达式 的运算符位于操作符之前。 2)举例说明:(3+4)*5-6 对应的前缀表达式就是 - *

    2024年02月03日
    浏览(49)
  • 数据结构——前缀、中缀、后缀表达式实现和转换(Java)

    1.7.1 概念 它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于 运算符相对与操作数的位置 不同 前缀 表达式的运算符位于与其相关的 操作数之前 ;中缀和后缀同理。 平时我们 日常使用 并最为熟悉的就是中缀表达式。如: 1 + 2 *

    2024年02月05日
    浏览(45)
  • Java LeetCode篇-深入了解关于栈的经典解法(栈实现:中缀表达式转后缀)

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍     文章目录         1.0 中缀表达式转后缀说明         1.1 实现中缀表达式转后缀思路         2.0 逆波兰表达式求值         2.1 实现逆波兰表达式求值思路         3.0 有效的括号         3.1 实现有

    2024年02月04日
    浏览(48)
  • 【数据结构】一篇文章带你彻底学会《后缀表达式》

    创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡𖥦)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 🔥c语言系列专栏:c语言之路重点知识整合 🔥 给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ 后缀表

    2024年02月05日
    浏览(48)
  • Python常用基础语法知识点大全合集,看完这一篇文章就够了

    Python 是一门独特的语言,快速浏览一下他的要点: 面向对象:每一个变量都是一个类,有其自己的属性(attribute)与方法(method)。 语法块:用缩进(四个空格)而不是分号、花括号等符号来标记。因此,行首的空格不能随意书写。 注释:行内用“#”号,行间注释写在两

    2023年04月22日
    浏览(47)
  • 中缀表达式求值(栈的应用)

    AcWing算法基础课-3302.表达式求值 给定一个表达式,其中运算符仅包含 +,-,*,/ (加 减 乘 整除),可能包含括号,请你求出表达式的最终值。 注意: 数据保证给定的表达式合法。 题目保证符号 - 只作为减号出现,不会作为负号出现,例如, -1+2 , (2+2)*(-(1+1)+2) 之类表达式均不

    2024年02月05日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包