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;
}
原文地址:https://www.cnblogs.com/zqxLonely/p/4919733.html