zoukankan      html  css  js  c++  java
  • 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
    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iomanip>
    using namespace std;
    
    class OPTR   //运算符栈
    {
    private:
        char s[1001];
        int length;
    
    public:
        OPTR()
        {
            length = -1;
        }
    
        char pop()
        {
            return s[length--];
        }
    
        void push(char c)
        {
            s[++length] = c;
        }
    
        char get_top()
        {
            return s[length];
        }
    
        void clear()
        {
            length = -1;
        }
    };
    
    class OPND  //操作数栈
    {
    private:
        double a[1001];
        int length;
    
    public:
        OPND()
        {
            length = -1;
        }
    
        double pop()
        {
            return a[length--];
        }
    
        void push(double b)
        {
            a[++length] = b;
        }
    
        double get_top()
        {
            return a[length];
        }
    
        void clear()
        {
            length = -1;
        }
    };
    
    double operate(double a, double b, char c)  //根据符号进行相应的运算
    {
        double result;
        if (c == '+')
            result = a + b;
    
        else if (c == '-')
            result = a - b;
    
        else if (c == '*')
            result = a*b;
    
        else if (c == '/')
            result = a / b;
    
        return result;
    }
    
    int get_position(char c)  //获取符号的下标
    {
        char s[] = { '+','-','*','/','(',')','=' };
        int i;
        int length;
        int position;
        
        position = -1;
        length = strlen(s);
        for (i = 0;i < length;i++)
        {
            if (s[i] == c)
            {
                position = i;
                break;
            }
        }
    
        return position;
    }
    
    char precede[][8]=    //优先级表
    {
        {'>','>','<','<','<','>','>'},
        {'>','>','<','<','<','>','>'},
        {'>','>','>','>','<','>','>'},
        {'>','>','>','>','<','>','>'},
        {'<','<','<','<','<','=',' '},
        {'>','>','>','>',' ','>','>'},
        {'<','<','<','<','<',' ','='}
    };
    
    bool in(char c)   //判断是不是操作数
    {
        char s[] = { '+','-','*','/','(',')','=' };
        int i;
        int length;
    
        length = strlen(s);
        for (i = 0;i < length;i++)
        {
            if (s[i]==c)
                break;
        }
    
        if (i<length)
            return true;
    
        else
            return false;
    }
    
    int main()
    {
        char s[1001];
        char temp[1001];
        int i;
        int j;
        int k;
        OPTR optr;
        OPND opnd;
        char top;
        int flag;
        int l;
        double a;
        double b;
        int length;
        int T;
    
        cin >> T;
        while (T--)
        {
            optr.clear();
            opnd.clear();
            optr.push('=');   //让第一个操作符与'='比较
    
            cin >> s;
            length = strlen(s);
            l = 0;
            flag = 0;
            for (i = 0;i<length;i++)
            {
                if (s[i] == '=' && optr.get_top() == '=')   //终止条件
                    break;
    
                if (in(s[i]) == false)
                {
                    temp[l++] = s[i];
                    flag = 1;
                }
    
                else
                {
                    if (flag == 1)
                    {
                        temp[l] = '';
                        flag = 0;
                        l = 0;
    
                        a = atof(temp);
                        opnd.push(a);
                    }
    
                    top = optr.get_top();
                    j = get_position(top);
                    k = get_position(s[i]);
    
                    if (precede[j][k] == '<')
                    {
                        optr.push(s[i]);
                    }
    
                    else if (precede[j][k] == '=')
                    {
                        optr.pop();
                    }
    
                    else if (precede[j][k] == '>')
                    {
                        b = opnd.pop();
                        a = opnd.pop();
                        optr.pop();
    
                        a = operate(a, b, top);
                        opnd.push(a);
                        i--;
                    }
                }
            }
            cout << setiosflags(ios::fixed) << setprecision(2) << opnd.get_top() << endl;
        }
        return 0;
    }
  • 相关阅读:
    Adventure C CF-665E(字典树、二进制)
    实验7投资问题
    Beautiful Array CF-1155D(DP)
    Salary Changing CF-1251D(二分)
    Beautiful Sets of Points CF-268C(乱搞)
    Vasya And Array CF1187C(构造)
    Tree Painting CF-1187E(换根DP)
    Vus the Cossack and Numbers CF-1186D(思维)
    Tree POJ-1741(点分治+树形DP)
    Magical Girl Haze 计蒜客-A1958(分层最短路)
  • 原文地址:https://www.cnblogs.com/zqxLonely/p/4919733.html
Copyright © 2011-2022 走看看