中缀表达式转化为后缀表达式
一、从应对考试角度来(在最快的时间内得出最准确的答案)
首先我们应该知道,要想将中缀转化为后缀,需要借助堆栈实现。(不准备画图了,画图有点浪费时间)我会用最简单明了的语言使读者弄懂。[举个例子吧:比如将:2*(9+6/3-5)+4转化为后缀表达式2 9 6 3 / +5 - * 4 + ]
1、任何中缀表达式都由运算数,运算符,括号(大,中,小),这三部分组成。
2、从中缀表达式的左边开始扫描(脑中自己想像的),若遇到运算数时,则直接将其输出(不压入堆栈)。
3、若遇到左括号,则将其压栈。
4、若遇到右括号,表达括号内的中缀表达式已经扫描完毕。这时需将栈顶的运算符依次弹出并输出,直至遇到左括号[左括号弹出但不输出]。
5、若遇到的是运算符:a、如果该运算符的优先级大于栈顶运算符的优先级时,将其压栈
b、如果该运算符的优先级小于栈顶运算符的优先级时,将栈顶运算符弹出并输出,接着和新的栈顶运算 符比较,若大于,则将其压栈,若小于,继续将栈顶运算符弹出并输出......(一直递归下去,直至运算符大于栈顶云算符为止)。
6、最后一步,若扫描到中缀表达式的末尾[即扫描结束],若堆栈中还有存留的运算符依次弹出并输出即可。
原文:https://blog.csdn.net/coder_dacyuan/article/details/79941743
CODE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | /* 中缀转后缀C++代码实现(比较方便) 1.遇到操作数:添加到后缀表达式中或直接输出 2.栈空时:遇到运算符,直接入栈 3.遇到左括号:将其入栈 4.遇到右括号:执行出栈操作,输出到后缀表达式,直到弹出的是左括号 注意:左括号不输出到后缀表达式 5.遇到其他运算符:弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈 6.将栈中剩余内容依次弹出后缀表达式 */ #include<iostream> #include<stack> #include<queue> #include<map> #include<string> #include<cstdio> #define MAX 100 using namespace std; //设置优先级(注意默认操作数的优先级最高,即其不需要进栈,进栈的都是运算符) map< char , int > p; //一些初始化******************************************** struct Node{ double num; //操作数 char op; //操作符 bool flag; //true表示操作数,false表示操作符 }; typedef struct Node node; stack<node> s; //操作符栈 stack<node> s1; //存放操作数的,为了计算后缀表达式的值 queue<node> q; //后缀表达式队列 //****************************************************** //中缀转后缀函数 void change( string str){ node temp; for ( int i = 0; i < str.length();){ if (str[i] == '(' ){ //3.遇到左括号:将其入栈 temp.flag = false ; temp.op = str[i]; s.push(temp); i++; } else if (str[i] == ')' ){ //4.遇到右括号:执行出栈操作,输出到后缀表达式,直到弹出的是左括号 while (!s.empty() && s.top().op != '(' ){ q.push(s.top()); s.pop(); } s.pop(); //弹出左括号 i++; } else if (str[i] >= '0' &&str[i] <= '9' ){ //如果是数字 temp.flag = true ; temp.num = str[i] - '0' ; i++; //后移一位,因为数字不一定是个位数 while (i < str.length() && str[i] >= '0' &&str[i] <= '9' ){ temp.num = temp.num * 10 + (str[i] - '0' ); i++; } q.push(temp); //操作数进入后缀表达式 } else { //如果是操作符 //5.遇到其他运算符:弹出所有优先加大于或等于该运算符的栈顶元素,然后将该运算符入栈 temp.flag = false ; while (!s.empty() && p[s.top().op] >= p[str[i]]){ q.push(s.top()); s.pop(); } temp.op = str[i]; s.push(temp); i++; } } //6.将栈中剩余内容依次弹出后缀表达式 while (!s.empty()){ q.push(s.top()); s.pop(); } } //************************************************************* //后缀表达式的计算 /* 从左到右扫描后缀表达式 1)若是操作数,就压栈, 2)若是操作符,就连续弹出两个操组数 3)栈顶的值即为所需结果 注:先弹出的是第一操作数,后弹出的是第二操作数 */ double calculate(){ double num_a, num_b; //操作数a,b node cur, temp; while (!q.empty()){ //后缀队列非空 cur = q.front(); //记录队首元素 q.pop(); if (cur.flag == true ){ //是操作数进入栈 s1.push(cur); } else { //是操作符就运算 num_b = s1.top().num; s1.pop(); //弹出第二操作数 num_a = s1.top().num; s1.pop(); //弹出第一操作数 temp.flag = true ; if (cur.op == '+' ){ temp.num = num_a + num_b; } else if (cur.op == '-' ){ temp.num = num_a - num_b; } else if (cur.op == '*' ){ temp.num = num_a * num_b; } else { temp.num = num_a / num_b; } s1.push(temp); //把计算后的结果再次压栈 } } return s1.top().num; } //************************************************************* int main() { string str; p[ '+' ] = p[ '-' ] = 1; //通过hashmap赋值 p[ '*' ] = p[ '/' ] = 2; cin >> str; change(str); //***************************************************** //中缀转后缀 /* while (!q.empty()){ cur = q.front(); if (cur.flag == true ) cout << cur.num << " " ; else cout << cur.op << " " ; q.pop(); }*/ while (!s1.empty()){ //初始化栈s1 s1.pop(); } double answer=calculate(); cout << answer<<endl; return 0; } |
分类:
其他——表达式计算
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥