这道题与 蓝桥杯 算法训练 表达式计算 一样
思路:
先要学会将中缀表达式转换为后缀表达式:中缀表达式转换为后缀表达式。在符号栈底加一个 '(' 防止栈为空,在字符串中加一个 " ."(空格 + '.') ,将栈的运算符全部提取出来。
检测到")" 不入栈, 而是将符号栈中的"(" 之上的运算符提出来,供给栈顶次顶元素运算,并将栈顶和次顶两个元素删除得到的新的值存入数值栈。碰到“.”,就按碰到+-运算符的处理方案一样。最后数值栈的那个值(既是栈顶也是栈底)即为运算结果。
参考博客:https://blog.csdn.net/qq_36238595/article/details/54730341#commentsedit
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
stack<char> ch; //符号栈
stack<double> num; //数值栈
char s[210];
char a[210];
void zhan1() //这个函数只接收+-号,+-号等级最低,运算符栈中除了括号外 都可以取出运算
{
double x,y,m;
while(ch.top()!='(') //从运算符栈中取一个运算符 对数值栈顶和次顶元素进行运算
{
x = num.top();
num.pop();
y = num.top();
num.pop();
switch(ch.top())
{
case '+':
m = y+x;
break;
case '-':
m = y-x;
break;
case '*':
m = y*x;
break;
case '/':
m = y/x;
break;
}
ch.pop();
num.push(m);
}
}
void zhan2() //只接受 * / , */的优先级比+-的高,所以不能将+-取出
{
double x,y,m;
while(ch.top()=='*' || ch.top()=='/')
{
x = num.top();
num.pop();
y = num.top();
num.pop();
switch(ch.top())
{
case '*':
m = y*x;
break;
case '/':
m = y/x;
break;
}
ch.pop();
num.push(m);
}
}
int main()
{
while(1)
{
gets(s);
int len = strlen(s);
if(s[0]=='0' && len==1)
break;
ch.push('(');
strcat(s," .");
//printf("%s\n",s);
int k = 0;
for(int i=0;s[i];i++)
{
if(s[i]>='0' && s[i]<='9')
{
a[k++] = s[i];
continue;
}
a[k]='\0';
if(a[0]!='\0' && s[i]==' ')
{
double w = atoi(a);
num.push(w);
a[0] = '\0';
k = 0;
continue;
}
switch(s[i])
{
case '+':
zhan1();
ch.push('+');
break;
case '-':
zhan1();
ch.push('-');
break;
case '*':
zhan2();
ch.push('*');
break;
case '/':
zhan2();
ch.push('/');
break;
case '(':
ch.push('(');
break;
case ')':
zhan1();
ch.pop();
break;
case '.':
zhan1();
ch.pop();
break;
}
}
printf("%.2lf\n",num.top());
}
return 0;
}