SJUKY111 计算表达式
⭐️难度:中等(其实很难)
⭐️类型:栈
📖题目:题目链接

🌟思路:
⭕️要把字符转换成浮点数,而不是整数,因为除法可能会产生小数
1️⃣需要两个栈:
1、操作数栈
2、符号栈
2️⃣符号栈规则:
1、栈空,直接进栈
2、进栈元素大于 栈顶元素,压栈,
3、进栈元素小于或等于栈顶元素,出栈
记忆:
老大来了,鸠占鹊巢
小弟来了,掩护被关的同伴和老大先走
3️⃣
符号栈出栈运算需要 循环 执行,因为要:
①循环弹出大或等于 进栈元素的运算符,如:栈:- 、 * 进+
②输入结束后依次弹出栈顶元素,如:栈:- 、 * 进\0
📚题解:
cpp
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<vector> // vector不需要.h
#include<list>
#include<set> // // 可以用 set 和 multiset
#include<unordered_set> // 可以用 unordered_set 和 unordered_multiset
#include<map> // 可以用 map 和 multimap
#include<unordered_map> // 可以用 unordered_map 和 unordered_multimap
#include<algorithm>
#include<string>
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
int main() {
// 用一个map保存各符号优先级
map<char, int> youxianji = {
{'\0',1},
{'+',2},{'-',2},
{'/',3},{'*',3}
};
char a[1000] = { 0 };
while (scanf("%s", a) != EOF) {
string numstr = ""; // 用一个字符串存数字
stack<double> nums; // 存操作数
stack<char> fuhaos; // 存操作符
for (int i = 0;;i++) { // 不在这里写退出条件,因为就算输入结束,也要将符号栈执行完
if (a[i] >= '0' && a[i] <= '9') {
numstr.push_back(a[i]);
}
else {
double num = stod(numstr); // 将字符串转成double型
nums.push(num);
numstr = ""; // 易漏:刷新numstr
//fuhaos.push(a[i]); // 操作符先不急着进栈,要先判断栈内情况
// 循环出栈
// 出栈的情况:栈不为空 且 进栈元素优先级小于或等于栈顶元素
while (!fuhaos.empty() &&
youxianji[a[i]] <= youxianji[fuhaos.top()]) {
double rhs = nums.top(); // 先弹出是右操作数
nums.pop();
double lhs = nums.top();
nums.pop();
char fuhao = fuhaos.top();
fuhaos.pop();
if (fuhao == '+') {
nums.push(lhs + rhs);
}
else if (fuhao == '-') {
nums.push(lhs - rhs);
}
else if (fuhao == '*') {
nums.push(lhs * rhs);
}
else if (fuhao == '/') {
nums.push(lhs / rhs);
}
}
// 如果输入结束,输出结果
if (a[i] == '\0') {
printf("%d\n",(int)nums.top()); // 结果保留整数,先强转成int
break;
}
// 如果栈空了 或 栈进栈元素优先级大于栈顶元素,直接进栈
if (fuhaos.empty() || youxianji[a[i]] > youxianji[fuhaos.top()]) {
fuhaos.push(a[i]);
}
}
}
}
return 0;
}