• 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;
    //}
    
  • 相关阅读:
    senium
    学习记录
    方法参数化
    洛谷1892 团伙
    洛谷2661 信息传递
    洛谷2661 信息传递
    洛谷1576最小花费
    洛谷1576最小花费
    最短路 Dijkstra模板
    堆排(模板)
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/7264836.html
Copyright © 2020-2023  润新知