正在上传…重新上传取消
搜索
正在上传…重新上传取消
详解中缀表达式转化为后缀表达式并求值,附代码解释
正在上传…重新上传取消
正在上传…重新上传取消于 2021-03-10 15:27:44 发布100 收藏
版权
19 篇文章0 订阅
订阅专栏
思路
首先我们需要知道如何转化表达式并求值:首先不同的运算符有不同的优先级:对于(,),优先级最高,其次是*,/,最低是+,-。在从左往右扫描字符串时,遇到数字,就将其直接压入数组中。遇到操作符时,如果当前栈为空,那么直接压入栈中,如果栈不为空,那么将栈顶操作符优先级大于等于当前操作符的操作符pop出栈,并压入数组,直到栈顶操作符优先级小于当前操作符或栈为空才停止此次操作,并将当前操作符压入栈中。
由于在我的代码中遇到左括号是直接递归,右括号return,因此上面的处理中不需要考虑括号。
得到表达式后,我们就需要进行求值,首先我们得到的是一个数组,其中按后缀表达式中的顺序存储着操作符以及数字。那么我们从左往右遍历数组,当遇到数字时,将其压入栈中,遇到操作符时,在栈中提取出两个元素,并将两个元素根据操作符计算得到的值压入栈中,最后栈顶元素即为表达式的值。
代码
#include <iostream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
void showAndPush(vector<string> &expr, const string &s, char t = ' ') {
expr.push_back(s);
cout << s << t;
}
bool isOper(const string &s) { //数组中可能出现-2,+2等元素,因此size()==1为前提。
return s.size() == 1 && (s[0] == '+' || s[0] == '-' || s[0] == '*' || s[0] == '/');
}
int cal(int num, int num1, char oper) {
switch (oper) {
case '+': return num + num1;
case '-': return num - num1;
case '*': return num * num1;
case '/': return num / num1;
}
}
//将输入的中缀表达式转化为后缀表达式
void infixToSuffix(int &p, const string &text, vector<string> &expr) {
stack<char> stk;
int len = text.length(), pre = expr.size();
for (; p < len; ++p) {
switch (text[p]) {
case '+':
case '-':
while (!stk.empty()) {
expr.emplace_back(1, stk.top());
cout << stk.top(); stk.pop();
}
stk.push(text[p]);
break;
case '*':
case '/':
while (!stk.empty() && (stk.top() == '*' || stk.top() == '/')) {
expr.emplace_back(1, stk.top());
cout << stk.top(); stk.pop();
}
stk.push(text[p]);
break;
case '(':
infixToSuffix(++p, text, expr); //遇到左括号就递归,将括号中的表达式当成一个独立的表达式,即可解决优先级的问题
break;
case ')':
while (!stk.empty()) {
showAndPush(expr, string(1, stk.top()));
stk.pop();
}
return;
case ' ': //遇到空格直接跳过不用处理
break;
default:
string num;
if (pre == expr.size() && !stk.empty()) { //这条if语句用于处理-2,(+2)等情况。这种情况下-+不算操作符。
num.push_back(stk.top());
stk.pop();
}
while (isdigit(text[p])) {
num.push_back(text[p]);
++p;
}
--p;
showAndPush(expr, num);
}
}
while (!stk.empty()) { //将栈中剩下的操作符全部压入数组中
showAndPush(expr, string(1, stk.top()));
stk.pop();
}
}
int calculate(const vector<string> &expr) { //根据后缀表达式数组进行求值。
stack<int> num;
for (auto &iter : expr) {
if (isOper(iter)) { //遇到操作符就将栈顶的两个元素出栈并求值,将结果再压入栈中,注意两个元素的顺序。
int t = num.top(); num.pop();
int t1 = num.top(); num.pop();
num.push(cal(t1, t, iter[0]));
} else {
num.push(stoi(iter));
}
}
return num.top(); //栈顶元素即为结果
}
void sln() {
string text;
getline(cin, text);
vector<string> expr;
int p = 0;
infixToSuffix(p, text, expr); //将中缀表达式转化为后缀表达式
cout << endl;
cout << calculate(expr) << endl; //对后缀表达式求值
}
int main() {
sln();
return 0;
}
- 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
已关注
-
正在上传…重新上传取消0 -
正在上传…重新上传取消 - 正在上传…重新上传取消0
-
正在上传…重新上传取消0 -
正在上传…重新上传取消
专栏目录
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
相关推荐
正在上传…重新上传取消
04-09
c语言实现中缀表达式转后缀表达式并求得计算结果,用顺序栈结构。 当输入者输入错误信息的时候需要报错,并说明错误的种类。
正在上传…重新上传取消
正在上传…重新上传取消 362
正在上传…重新上传取消
Python中缀表达式转后缀表达式并求值_滑稽研究所的博客...
4-26
正在上传…重新上传取消
...求值_leoyongyuan的博客_中缀表达式转后缀表达式并求值
3-10
正在上传…重新上传取消
正在上传…重新上传取消 490
正在上传…重新上传取消
算术中缀表达式转化成后缀表达式,并利用后缀表达式求值(操作数为个位数)
正在上传…重新上传取消 2068
正在上传…重新上传取消
2-6
正在上传…重新上传取消
正在上传…重新上传取消 5万+
正在上传…重新上传取消
正在上传…重新上传取消 1868
正在上传…重新上传取消
正在上传…重新上传取消 2万+
正在上传…重新上传取消
正在上传…重新上传取消 1419
正在上传…重新上传取消
正在上传…重新上传取消 694
正在上传…重新上传取消
正在上传…重新上传取消 14万+
正在上传…重新上传取消
正在上传…重新上传取消 295
正在上传…重新上传取消
正在上传…重新上传取消 3525
正在上传…重新上传取消
正在上传…重新上传取消 168
正在上传…重新上传取消
正在上传…重新上传取消 1551
正在上传…重新上传取消
正在上传…重新上传取消 729
正在上传…重新上传取消
正在上传…重新上传取消 1万+
正在上传…重新上传取消
正在上传…重新上传取消 333
“相关推荐”对你有帮助么?
-
正在上传…重新上传取消
非常没帮助
-
正在上传…重新上传取消
没帮助
-
正在上传…重新上传取消
一般
-
正在上传…重新上传取消
有帮助
-
正在上传…重新上传取消
非常有帮助
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
- 公安备案号11010502030143
- 京ICP备19004658号
- 京网文〔2020〕1039-165号
- 经营性网站备案信息
- 北京互联网违法和不良信息举报中心
- 家长监护
- 网络110报警服务
- 中国互联网举报中心
- Chrome商店下载
- ©1999-2022北京创新乐知网络技术有限公司
- 版权与免责声明
- 版权申诉
- 出版物许可证
- 营业执照
正在上传…重新上传取消
码龄4年正在上传…重新上传取消 暂无认证
1万+
访问
正在上传…重新上传取消
等级
675
积分
17
粉丝
23
获赞
13
评论
19
收藏
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
热门文章
- python中的jieba分词保留给定词汇 正在上传…重新上传取消 1138
- 关于java中控件的默认字体 正在上传…重新上传取消 964
- 字符串经过多次转义后得到反斜杠 正在上传…重新上传取消 797
- 我太菜了啊 正在上传…重新上传取消 361
- hdu - 6681 Rikka with Cake 线段树 正在上传…重新上传取消 324
分类专栏
- c++19篇
- 杂2篇
- python1篇
- 字典树1篇
- 并查集4篇
- DP7篇
- 线段树13篇
- KMP1篇
- 模拟2篇
- 数学1篇
- DFS9篇
- 最短路
- 心情1篇
- 树链剖分6篇
- java1篇
- BFS2篇
- Codeforces8篇
正在上传…重新上传取消
最新评论
- hdu - 6681 Rikka with Cake 线段树
asblah: 清晰易懂,好强啊
- 我太菜了啊
Chen_hsuan 回复 CoAAColA: 你这是叛逃!
- 我太菜了啊
CoAAColA 回复 Vwsrenzk: 搞呀
您愿意向朋友推荐“博客详情页”吗?
-
正在上传…重新上传取消
强烈不推荐
-
正在上传…重新上传取消
不推荐
-
正在上传…重新上传取消
一般般
-
正在上传…重新上传取消
推荐
-
正在上传…重新上传取消
强烈推荐
最新文章
正在上传…重新上传取消
正在上传…重新上传取消举报