nyoj(表达式求值)

描述
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<stdio.h>
#include<string.h>
#include<stdlib.h>
int map[7][7]=    //算符间的优先关系,100表示不会出现的情况
{
    {1,1,-1,-1,-1,1,1},
    {1,1,-1,-1,-1,1,1},
    {1,1,1,1,-1,1,1},
    {1,1,1,1,-1,1,1},
    {-1,-1,-1,-1,-1,0,100},
    {1,1,1,1,100,1,1},
    {-1,-1,-1,-1,-1,100,0}
};
int cam(char c)
{
    switch(c)
    {
    case '+':
        return 0;
    case '-':
        return 1;
    case '*':
        return 2;
    case '/':
        return 3;
    case '(':
        return 4;
    case ')':
        return 5;
    case '#':
        return 6;
    }
}
double sol(double x,char c,double y)
{
    switch(c)
    {
    case '+':
        return x+y;
    case '-':
        return x-y;
    case '*':
        return x*y;
    case '/':
        return x/y;
    }
}
int z(char c)
{
    if('0'<=c&&c<='9'||c=='.')
        return 1;
    if(c==' ')
        return -1;
    return 0;
}
char str[1005];
char optr[1005];
double opnd[1005];
int main()
{
    int t1,t2,k,len;
    char ch,zz;
    int temp1,temp2;
    double a,b;
    int t;
    scanf("%d",&t);
    getchar();
    while(t--)
    {
        gets(str);
        len=strlen(str);
        str[len-1]='#'; //处理的等于号
        t1=t2=k=0;
        optr[t1++]='#';
        ch=str[k++];
        while(ch!='#'||optr[t1-1]!='#')
        {
            if(z(ch)==1)  //操作数入栈
            {
                opnd[t2++]=atof(&str[k-1]); //把字符串转换成浮点数
                while(z(str[k])==1)
                    k++;
                ch=str[k++];
            }
            else if(z(ch)==-1)
                ch=str[k++];
            else
            {
                temp1=cam(optr[t1-1]);
                temp2=cam(ch);
                if(map[temp1][temp2]==-1)  //栈顶元素优先权低
                {
                    optr[t1++]=ch;
                    ch=str[k++];
                }
                else if(map[temp1][temp2]==0) //脱括号并接受下一个字符
                {
                    t1--;
                    ch=str[k++];
                }
                else    //退栈并将运算结果
                {
                    zz=optr[--t1];
                    a=opnd[--t2];
                    b=opnd[--t2];
                    opnd[t2++]=sol(b,zz,a);
                }
            }
        }
        printf("%.2lf
",opnd[0]);
    }
    return 0;
}





//#include<stdio.h>
//#include<stdlib.h>
//
////数据栈
//typedef struct DA
//{
//    float data[1000];
//    int pop;
//} SDA;
//
////运算符栈
//typedef struct OP
//{
//    char op[1000];
//    int pop;
//} SOP;
//
////初始化数据栈
//int InitSDA(SDA * p)
//{
//    p->pop = 0;
//    return 0;
//}
//
////初始化运算符栈
//int InitSOP(SOP * p)
//{
//    p->pop = 0;
//    (p->op[p->pop]) = '=';
//    (p->pop)++;
//    return 0;
//}
//
////数据入栈
//int PushSDA(SDA * p, float d)
//{
//    if(p->pop < 1000)
//    {
//        p->data[p->pop] = d;
//        (p->pop)++;
//        return 0;
//    }
//    else
//        return 1;   //栈满
//}
//
////运算符入栈
//int PushSOP(SOP * p, char c)
//{
//    if(p->pop < 1000)
//    {
//        p->op[p->pop] = c;
//        (p->pop)++;
//        return 0;
//    }
//    else
//        return 1;   //栈满
//}
//
////数据出栈
//int PopSDA(SDA * p, float * d)
//{
//    (p->pop)--;
//    if(p->pop >= 0)
//    {
//        *d = p->data[p->pop];
//        return 0;
//    }
//    else
//        return 1;
//}
//
////运算符出栈
//int PopSOP(SOP * p, char * c)
//{
//    (p->pop)--;
//    if(p->pop >= 0)
//    {
//        *c = p->op[p->pop];
//        return 0;
//    }
//    else
//        return 1;
//}
//
////从s[*pc]开始获取一个浮点数
//int StrToInt(char s[], int * pc, float *pout)
//{
//    char buf[100];
//    int i = 0;
//
//    if(s[*pc]<'0' || s[*pc]>'9')
//        return 1;
//    else
//    {
//        while((s[*pc] >= '0' && s[*pc] <= '9') || s[*pc] == '.')
//        {
//            buf[i] = s[*pc];
//            (*pc)++;
//            i++;
//        }
//        buf[i] = '';
//        *pout = (float)atof(buf);
//        return 0;
//    }
//}
//
////从s[*pc]获取一个char
//int StrToChar(char s[], int *pc, char *pout)
//{
//    if('+'==s[*pc]||'-'==s[*pc]||'*'==s[*pc]||'/'==s[*pc]||'('==s[*pc]||')'==s[*pc])
//    {
//        *pout = s[*pc];
//        (*pc)++;
//        return 0;
//    }
//    else
//        return 1;
//}
//
////获取优先级
//char GetPri(char c1, char c2)
//{
//
//    char f[7][7] = {'>', '>', '<', '<', '<', '>', '>',
//                    '>', '>', '<', '<', '<', '>', '>',
//                    '>', '>', '>', '>', '<', '>', '>',
//                    '>', '>', '>', '>', '<', '>', '>',
//                    '<', '<', '<', '<', '<', '=', '',
//                    '>', '>', '>', '>', '', '>', '>',
//                    '<', '<', '<', '<', '<', '', '=',
//                   };
//
//    int i=0, j=0;
//    switch(c1)
//    {
//    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;
//    }
//    switch(c2)
//    {
//    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;
//    }
//    return f[i][j];
//}
//
////计算表达式
//float Operate(float a, char op, float b)
//{
//    switch(op)
//    {
//    case '+':
//        return a + b;
//    case '-':
//        return a - b;
//    case '*':
//        return a * b;
//    case '/':
//        return a / b;
//    default:
//        return 0;
//    }
//}
//
//int main(void)
//{
//    char s[10][1000];
//    int c = 0;
//    float bufda;
//    char bufop;
//    float a, b;
//    SDA sda;
//    SOP sop;
//    int n;
//    int i;
//
//    scanf("%d", &n);
//    for(i = 0; i < n; i++)
//        scanf("%s", s[i]);
//    for(i = 0; i < n; i++)
//    {
//        c = 0;
//        InitSDA(&sda);  //初始化数据栈
//        InitSOP(&sop);  //初始化符号栈
//        while(s[i][c] != '=' || sop.op[sop.pop - 1] != '=') //  计算未完成
//        {
//            if(0 == StrToInt(s[i], &c, &bufda))
//                PushSDA(&sda, bufda);   //数据入栈
//            else
//            {
//                switch(GetPri(sop.op[sop.pop - 1], s[i][c]))
//                {
//                case '<':
//                    if(0 == StrToChar(s[i], &c, &bufop))
//                        PushSOP(&sop, bufop);
//                    break;
//                case '=':
//                    PopSOP(&sop, &bufop);
//                    c++;
//                    break;
//                case '>':
//                    PopSOP(&sop, &bufop);
//                    PopSDA(&sda, &b);
//                    PopSDA(&sda, &a);
//                    PushSDA(&sda, Operate(a, bufop, b));
//                    break;
//                }
//            }
//        }
//        PopSDA(&sda, &a);
//        printf("%.2f
", a);
//    }
//    return 0;
//}
//


//C++
//#include<queue>
//#include<stack>
//#include<vector>
//#include<math.h>
//#include<cstdio>
//#include<sstream>
//#include<numeric>//STL数值算法头文件
//#include<stdlib.h>
//#include <ctype.h>
//#include<string.h>
//#include<iostream>
//#include<algorithm>
//#include<functional>//模板类头文件
//using namespace std;
//
//const int INF=0x3f3f3f3f;
//const int maxn=110000;
//typedef long long ll;
//
//int priority(char c)
//{
//    if(c == '=')    return 0;
//    if(c == '+')    return 1;
//    if(c == '-')    return 1;
//    if(c == '*')    return 2;
//    if(c == '/')    return 2;
//    return 0;
//}
//
//void compute(stack<double>& Num,stack<char>& Op)
//{
//    double b = Num.top();
//    Num.pop();
//    double a = Num.top();
//    Num.pop();
//    switch(Op.top())
//    {
//    case '+':
//        Num.push(a+b);
//        break;
//    case '-':
//        Num.push(a-b);
//        break;
//    case '*':
//        Num.push(a*b);
//        break;
//    case '/':
//        Num.push(a/b);
//        break;
//    }
//    Op.pop();
//}
//
//int main()
//{
//    int z;
//    char str[1005];
//    stack<double> Num;
//    stack<char> Op;
//    scanf("%d",&z);
//    while(z--)
//    {
//        scanf("%s",str);
//        int len = strlen(str);
//        for(int i=0; i<len; i++)
//        {
//            if(isdigit(str[i]))
//            {
//                double n = atof(&str[i]);
//                while(i<len && (isdigit(str[i]) || str[i]=='.'))
//                    i++;
//                i--;
//                Num.push(n);
//            }
//            else
//            {
//                if(str[i] == '(')
//                    Op.push(str[i]);
//                else if(str[i] == ')')
//                {
//                    while(Op.top()!='(')
//                        compute(Num,Op);
//                    Op.pop();
//                }
//                else if(Op.empty() || priority(str[i])>priority(Op.top()))
//                    Op.push(str[i]);
//                else
//                {
//                    while(!Op.empty() && priority(str[i])<=priority(Op.top()))
//                        compute(Num,Op);
//                    Op.push(str[i]);
//                }
//            }
//        }
//        Op.pop();
//        printf("%.2f
",Num.top());
//        Num.pop();
//    }
//    return 0;
//}
原文地址:https://www.cnblogs.com/nyist-xsk/p/7264836.html