nyoj35表达式求值



 

/*表达式求值
时间限制:3000 ms  |  内存限制:65535 KB
难度:4
描述 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*/
//运用浮点数的读取。

 

<span style="font-size:18px;">#include<stdio.h>  
#include<string.h>  
#include<stack>  
#include<algorithm>  
using namespace std;  
//**判断算术符的优先级**//  
char precede(char a,char b)  
{  
    if(a=='+'||a=='-')  
    {  
        if(b=='+'||b=='-'||b==')'||b=='=') return '>';  
        else return '<';  
    }  
    if(a=='*'||a=='/')  
    {  
        if(b=='(') return '<';  
        else return '>';  
    }  
    if(a==')')  
    {  
        return '>';  
    }  
    if(a=='('||a=='=')  
    {  
        if(a=='('&&b==')'||a=='='&&b=='=') return '=';  
        else return '<';  
    }  
}  
//**算术符的运算**//  
double operate(double num1,char ch,double num2)  
{  
    double sum;  
    if(ch=='+')  
    {  
        sum=num1+num2;  
    }  
    if(ch=='-')  
    {  
        sum=num1-num2;  
    }  
    if(ch=='*')  
    {  
        sum=num1*num2;  
    }  
    if(ch=='/')  
    {  
        sum=num1/num2;  
    }  
    return sum;  
}  
int main()  
{  
    int ncases,i,k,len,flag;  
    double x,y;  
    char c,str[1001],a[1001];  
    //**建立两个栈,optr储存运算符,opnd存储double字符串(数字字符)**//  
    stack<char>optr;  
    stack<double>opnd;  
    optr.push('=');//**将起始'='作为栈底元素**//  
    scanf("%d",&ncases);  
    while(ncases--)  
    {  
        memset(str,0,sizeof(str));  
        memset(a,0,sizeof(a));  
        flag=0;k=0;  
        scanf("%s",str);  
        len=strlen(str);  
        for(i=0;i<=len-1;)  
        {  
            if(str[i]=='='&&optr.top()=='=')//**如果栈顶跟读取的‘=’相同,表示表达式求值完毕**//  
            {  
                break;  
            }  
            if((str[i]>='0'&&str[i]<='9')||str[i]=='.')//**读取浮点数读取,悲剧啊**//  
            {  
                flag=1;//**flag标记是否读取完这一串数字(浮点数)**//  
                a[k++]=str[i];  
                i++;  
                continue;  
            }  
            if(flag==1)  
            {  
                a[k]='\0';  
                opnd.push(atof(a));//**atof表示将字符串转化为浮点数(double型),atoi是转化为整型(int型)   
                flag=0;  
                k=0;  
            }  
            switch(precede(optr.top(),str[i]))  
            {  
            case '<'://**栈顶元素优先权低**//  
                optr.push(str[i]);  
                i++;  
                break;  
            case '='://**脱括号**//  
                optr.pop();  
                i++;  
                break;  
            case '>': //**退栈并讲运算结果入栈**//  
                c=optr.top();  
                optr.pop();  
                x=opnd.top();  
                opnd.pop();  
                y=opnd.top();  
                opnd.pop();  
                opnd.push(operate(y,c,x));  
                break;  
            }  
        }  
        printf("%.2lf\n",opnd.top());  
        opnd.pop();  
    }  
    return 0;  
}          </span>

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值