表达式求值
题目描述:
对于一个不存在括号的表达式进行计算
输入:
存在多种数据,每组数据一行,表达式中数字后存在空格
输出:
输出结果
样例输入:
6 / 2 + 3 + 3 * 4
样例输出:
18
wc,这个题,自己实现有很多很多坑
1.运算符优先级,自己的优先级小于自己!矩阵0多1少
2. 如果表达式中有空格,一定使用gets读取表达式!!
3.注意可能会需要使用double栈存储数字防止小数
如果表达式中有括号,左括号直接强制入栈!
右括号优先级比加减乘除都低。
1.左括号的优先级仅高于#;
2.但是遇见左括号时,不用和OPTR栈顶元素进行优先级比较,直接强制进OPTR栈;
3.遇到右括号,退OVS栈两次,退OPTR栈一次,进行相应的运算操作,将计算结果压入OVS栈,直到OPTR栈顶元素是左括号为止,并将左括号弹出OPTR栈;
#include<iostream>
#include<stack>
using namespace std;
stack<int> op;
stack<double> in;
char str[220];
//运算符优先级 0+-*/ 其中0是自定义的优先级最低的运算符
//值为1代表优先级高
int mat[][5]={
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0
};
//reto代表是运算符还是数字
//retn代表返回值 :运算符编号或者数字
//i是字符串标号
void getOp(bool &reto,int &retn,int &i)
{
//人为补充表达式首尾的两个低级运算符0
if(i==0&&op.empty()==true)
{
reto=true;
retn=0;
return;
}
if(str[i]==0)
{
reto=true;
retn=0;
return;
}
if(str[i]>='0'&&str[i]<='9')
{
reto=false;
}
else
{
reto=true;
if(str[i]=='+')
{
retn=1;
}
if(str[i]=='-')
{
retn=2;
}
if(str[i]=='*')
{
retn=3;
}
if(str[i]=='/')
{
retn=4;
}
i+=2;
//i向后移动 跨过当前运算符和空格
return;
}
//截取完整数字
retn=0;
for(;str[i]!=0&&str[i]!=' ';i++)
{
retn*=10;
retn+=str[i]-'0';
}
//如果题目说明数字后没空格,下面跳过空格的代码注释掉即可
if(str[i]==' ')
{
i++;
}
return;
}
int main()
{
while(gets(str))
{
if(str[0]=='0'&&str[1]==0)
{
break;
}
//重置清零操作
bool retop;
int retnum;
int idx=0;
while(!op.empty())
{
op.pop();
}
while(!in.empty())
{
in.pop();
}
//开始处理
while(true)
{
getOp(retop,retnum,idx);
if(retop==true)
{
if(op.empty()==true||mat[retnum][op.top()]==1)
{
op.push(retnum);
}
else
{
double n1,n2;
int o;
double result;
while(mat[retnum][op.top()]==0)
{
o=op.top();
op.pop();
n1=in.top();
in.pop();
n2=in.top();
in.pop();
if(o==1)
{
result=n1+n2;
}
else if(o==2)
{
result=n1-n2;
}
else if(o==3)
{
result=n1*n2;
}
else if(o==4)
{
result=n1/n2;
}
in.push(result);
}
op.push(retnum);
}
}
else
{
in.push(retnum);
}
if(op.size()==2&&op.top()==0)
{
break;
}
}
printf("%.2f\n",in.top());
}
return 0;
}