NYOJ35表达式求值

描述
ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
2
1.000+2/4=
((1+2)*5+1)/4=
样例输出
1.50

4.00


**难。。。只可意会,不可言传,思路是遇到括号先括号入栈,遇到符号先入栈,等遇到第二个符号的时候再判断前一个符号是否要计算,遇到反括号,清空括号里面的运算式(最后一定还要注意清除括号,我在这坑了一个小时)



#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
char s[1010];
stack<double> dsta; //数据栈
stack<char> csta; //字符栈 
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s",&s[1]);//从一号位置开始输入,0号位置留给下面的( 
int len=strlen(&s[1]);//也是从一号位置开始计数的 
s[0]='(';
s[len]=')';
for(int i=0;i<=len;i++)
{
if(s[i]=='(')//是'(' 直接入栈 
csta.push(s[i]);
else if(s[i]>='0' && s[i]<='9')//把字符变成double ,(会用的可以尝试atof()函数)。就是记录小数点后的位数p-i;然后用n/(10^(p-i)) 
{
double n=0;
int p=0;//记录小数点的位置 
while(s[i]>='0' && s[i]<='9'||s[i]=='.')
{
if(s[i]=='.')
p = i;
else
{
n = n*10 + (s[i]-'0');
}
i++;
}
i = i-1;//一定要减,不然外层for循环又多加 1 
if(p!=0)//有无小数点 
dsta.push(n/pow(10,i-p));
else
dsta.push(n);
}
else if(s[i]=='+' || s[i]=='-')
{
if(csta.top()=='(')//如果前面没运算符号的话就直接放入 
csta.push(s[i]);
else
{
double a,b,sum;
b = dsta.top();dsta.pop();
a = dsta.top();dsta.pop();
switch(csta.top())
{
case '+':sum = a + b;break;
case '-':sum = a - b;break;
case '*':sum = a * b;break;
case '/':sum = a / b;break;
}
dsta.push(sum);//放入计算后的值 
csta.pop();//删除上个运算付 
csta.push(s[i]);//放入当前运算符
}
}
else if(s[i]=='*' || s[i]=='/')
{
if(csta.top()=='(')
csta.push(s[i]);
else
{
double a,b,sum;
b = dsta.top();dsta.pop();
a = dsta.top();dsta.pop();
switch(csta.top())
{
case '+':dsta.push(a);dsta.push(b);csta.push(s[i]);break;//如果是+,-法的话,记得把拿出来的数给放回去哦!!好尴尬啊! 
case '-':dsta.push(a);dsta.push(b);csta.push(s[i]);break;
case '*':sum = a * b;dsta.push(sum);csta.pop();csta.push(s[i]);break;
case '/':sum = a / b;dsta.push(sum);csta.pop();csta.push(s[i]);break;
}
}

}
else if(s[i]==')')
{
while(csta.top()!='(')
{
double a,b,sum;
b = dsta.top();dsta.pop();
a = dsta.top();dsta.pop();
switch(csta.top())
{
case '+':sum = a + b;break;
case '-':sum = a - b;break;
case '*':sum = a * b;break;
case '/':sum = a / b;break;
}
dsta.push(sum);//放入计算后的值 
csta.pop();//删除上个运算付 
}
csta.pop();//就是它!!坑我半天,运算完成不要忘记抛出左括号 

}
printf("%.2lf\n",dsta.top());
dsta.pop();//最后清除一下; 
}
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值