NYOJ:35-表达式求值

来源:互联网 发布:陈华伟 知乎 编辑:程序博客网 时间:2024/06/06 14:10

表达式求值

时间限制: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

此题比较有代表性,搞清楚符号的优先级

代码:

#include <iostream>#include <string.h>#include <stdlib.h>#include <stdio.h>using namespace std;#define STACK_INIT_SIZE 1024#define STACKIN_INCREMENT 30char Precede_Matrix[7][7]={    {'>', '>', '<', '<', '<', '>', '>',},    {'>', '>', '<', '<', '<', '>', '>',},    {'>', '>', '>', '>', '<', '>', '>',},    {'>', '>', '>', '>', '<', '>', '>',},    {'<', '<', '<', '<', '<', '=', '0',},    {'>', '>', '>', '>', '0', '>', '>',},    {'<', '<', '<', '<', '<', '0', '=',}};char Precede(char a,char b){    int i=0,j=0;    switch(a)    {    case '+' :        i = 0;        break;    case '-' :        i = 1;        break;    case '*' :        i = 2;        break;    case '/' :        i = 3;        break;    case '(' :        i = 4;        break;    case ')' :        i = 5;        break;    case '#' :        i = 6;        break;    default :        cout << "Error1!" << endl;    }    switch(b)    {    case '+' :        j = 0;        break;    case '-' :        j = 1;        break;    case '*' :        j = 2;        break;    case '/' :        j = 3;        break;    case '(' :        j = 4;        break;    case ')' :        j = 5;        break;    case '#' :        j = 6;        break;    default :        cout << "Error1!" << endl;    }    return Precede_Matrix[i][j];}double Operate(double a,char oper,double b){    switch(oper)    {    case '+':        return a + b;    case '-':        return a- b;    case '*':        return a* b;    case '/':        return a / b;    default:        cout << "Error3!" << endl;        return -1;    }}struct stack_char{    char *base;    char *top;    int stacksize;};struct stack_double{    double *base;    double *top;    int stacksize;};template <class T2,class T1>//类模板void InitStack(T1 &S){    S.base=(T2*)malloc(STACK_INIT_SIZE*sizeof(T2));    if(!S.base)        cout<<"Overflow2!"<<endl;    S.top=S.base;    S.stacksize=STACK_INIT_SIZE;}template <class T2,class T1>void Push(T1 &S,T2 e){    if(S.top-S.base>=S.stacksize)    {        S.base=(T2*)realloc(S.base,(S.stacksize+STACKIN_INCREMENT)*sizeof(T2));        if(!S.base)            cout<<"Overflow3!"<<endl;        S.top=S.base+S.stacksize;        S.stacksize += STACKIN_INCREMENT;    }    *S.top++=e;}template <class T2,class T1>void Pop(T1 &S,T2 &e){    if(S.top==S.base)        cout << "Stack is empty!!" << endl;    e=*--S.top;}template <class T2,class T1>T2 GetTop(T1 S){    if(S.top==S.base)        cout << "Stack is empty!!" << endl;    return  *--S.top;}bool IsOperand(char c){    if(('0'<=c&&c<='9')||c=='.')        return true;    else        return false;}int main(){    string str;    int T;    cin>>T;    while(T--)    {        cin>>str;        str[str.length()-1]='#';        // str.push_back('#');//  最后是#(结束标志)        double a,b;        char x;        char theta;        stack_char OPTR;        InitStack<char>(OPTR);        Push(OPTR,'#');        stack_double OPND;        InitStack<double> (OPND);        int i=0;        char c=str[i++];//        double operand=0;        while(!(c=='#'&&GetTop<char>(OPTR)=='#'))        {            if(IsOperand(c))            {                operand=atof(&str[i-1]); //把从c开头的数转化成double                Push(OPND,operand);                while(IsOperand(str[i]))                    i++;                c=str[i++];            }            else            {                switch(Precede (GetTop<char> (OPTR), c))                {                case '<':                    Push(OPTR,c);                    c=str[i++];                    break;                case '=':                    Pop(OPTR,x);                    c=str[i++];                    break;                case '>':                    Pop(OPTR,theta);                    Pop(OPND,b);                    Pop(OPND,a);                    Push(OPND,Operate(a, theta, b));                    break;                default:                    cout<<"operator Error!"<<endl;                    break;                }            }        }        printf("%0.2lf\n",GetTop<double>(OPND));        //cout<<GetTop<double>(OPND)<<endl;        free(OPTR.base);        free(OPND.base);    }    return 0;}
原创粉丝点击