传送门
题目大意:给出一个不含括号的且只含加减乘除运算符和数字的字符串作为待计算的中缀表达式。运算符的计算规则依据下方图片中描述的形式给出。目的:求中缀表达式的值。
解题思路:定义两个栈,一个操作符栈,一个运算数栈。首先遍历表达式,遇到操作数直接入栈,遇到运算符将优先级高的 “乘除”(实际意义中的乘除,接下来的加减也是实际意义中的加减)做相应的运算并在操作数栈中存入运算后的结果;将优先级低的 “加减” 堆进运算符栈。
经过上述的一遍操作,最后会留下一个只含加减运算以及相应的运算数在表达式中。
例如: 将 1 ∗ 2 + 4 ∗ 6 − 8 / 4 − 2 经 过 遍 历 一 遍 操 作 后 可 得 将1*2+4*6-8/4-2经过遍历一遍操作后可得 将1∗2+4∗6−8/4−2经过遍历一遍操作后可得
操 作 后 结 果 : 2 + 24 − 2 − 2 操作后结果:2+24-2-2 操作后结果:2+24−2−2
这个结果是存储在我们之前定义的运算符栈和操作数栈中的,很明显会发现,因运算符都是双目运算符,固最后剩余运算数的个数要比操作符的个数多一个。最终只需从前往后计算即可。
上代码:
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 500010;
char op[N];
double num[N];
int s, t;
int main()
{
string str1,str;
getline(cin, str1);
int len = str1.size();
for(int i=0;i<len;i++)
{
if(str1[i]!=' ')
{
str+=str1[i];
}
}
len = str.size();
for (int i = 0;i < len;i++)
{
if(str[i]==' ') continue;
if (str[i] >= '0' && str[i] <= '9')
{
int j = i;
double sum = 0;
while (str[j] >= '0' && str[j] <= '9' && j < len)
{
sum = sum * 10 + str[j] - '0';
j++;
}
num[++s] = sum * 1.0;
i = j - 1;
}
else {
if (str[i] == '*' || str[i] == '/')
{
op[++t] = str[i];
}
else {
int j = i + 1;
double sum = 0;
while (str[j] >= '0' && str[j] <= '9' && j < len)
{
sum = sum * 10 + str[j] - '0';
j++;
}
if (str[i] == '+')
{
if (sum < 1e-6)
{
puts("Cannot be divided by 0");
return 0;
}
else num[s] /= sum;
}
else if (str[i] == '-')
{
num[s] *= sum;
}
i = j - 1;
}
}
}
double ans = num[1];
for (int i = 1;i <= t;i++)
{
if (op[i] == '*')
{
ans -= num[i + 1];
}
else ans += num[i + 1];
}
printf("%.2lf", ans);
return 0;
}