ACM--表达式求值实现

  这个是南阳OJ上的第35题,地址:点击打开链接

   

表达式求值

时间限制: 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 <stdio.h>
#include <stdlib.h>
#include<stack>
#include<string.h>
using namespace std;
bool IsOperator(char ch);
char Precede(char opr1, char opr2);
double Operate(double opnd1, char op, double opnd2);
int ConvertToIndex(char opr);
/**
  这个是用来判断一个字符是不是
  操作符的
*/
bool IsOperator(char ch)
{
    if (ch == '+' || ch == '-' ||
        ch == '*' || ch == '/' ||
        ch == '(' || ch == ')' || ch == '=')
        return true;
    else
        return false;

}

//运算符的优先关系
                         //'+', '-', '*', '/', '(', ')', '#'
char OprRelation[7][7] = {{'>', '>', '<', '<', '<', '>', '>'}, //'+'
                          {'>', '>', '<', '<', '<', '>', '>'}, //'-'
                          {'>', '>', '>', '>', '<', '>', '>'}, //'*'
                          {'>', '>', '>', '>', '<', '>', '>'}, //'/'
                          {'<', '<', '<', '<', '<', '=', ' '}, //'('
                          {'>', '>', '>', '>', ' ', '>', '>'}, //')'
                          {'<', '<', '<', '<', '<', ' ', '='}};//'#'
/**
   这个是用来获取每一个操作符的优先级

*/
int ConvertToIndex(char opr)
{
    int index;

    switch (opr)
    {
    case '+':
        index = 0;
        break;
    case '-':
        index = 1;
        break;
    case '*':
        index = 2;
        break;
    case '/':
        index = 3;
        break;
    case '(':
        index = 4;
        break;
    case ')':
        index = 5;
        break;
    case '=':
        index = 6;
        break;
    }

    return index;
}
/**
   这个是用来获取连个字符的优先级
*/
char Precede(char opr1, char opr2)
{
    int index1 = ConvertToIndex(opr1);
    int index2 = ConvertToIndex(opr2);

    return OprRelation[index1][index2];
}
/**
    这个是用来对两个数进行求值
*/
double Operate(double opnd1, char op, double opnd2)
{
    double ret;

    switch(op)
    {
    case '+':
        ret = opnd1 + opnd2;
        break;
    case '-':
        ret = opnd1 - opnd2;
        break;
    case '*':
        ret = opnd1 * opnd2;
        break;
    case '/':
        ret = opnd1 / opnd2;
        break;
    }

    return ret;
}

//算符优先算法
double CaculateExpression(string exp)
{
    stack<char> optr; //只处理+ - # / ()运算
    stack<double> opnd;  //只处理0-9的整数运算
    char ch;
    int i = 0;
    optr.push('=');
    ch = exp[i++];
   bool flag = true;
    //如果##配对,表达式求值完成
    while (flag&&(ch != '=' || optr.top() != '='))
    {
        if (!IsOperator(ch))
        {
             string f,g;
             f=exp[i-1];
             g.append(f);
             while(!IsOperator(exp[i])){
                    f=exp[i];
                   g.append(f);
                   ++i;
             }
             double value = atof(g.c_str());
              //操作数入栈
                 opnd.push(value);
                 ch = exp[i++];
        }
        else
        {
            //比较栈顶操作符和新取得的操作符的优先关系
            switch (Precede(optr.top(), ch))
            {
            case '<'://栈顶优先权低
                optr.push(ch);
                ch = exp[i++];
                break;
            case '='://括号配对,栈顶括号弹出
                optr.pop();
                if(exp.length()==i){
                   flag=false;
                }else{
                    ch = exp[i++];
                }
                break;
            case '>'://栈顶优先权高,先弹出,计算,结果操作数入栈
                char op = optr.top();
                optr.pop();
                double num2 = opnd.top();//第二个操作数在前
                opnd.pop();
                double num1 = opnd.top();
                opnd.pop();

                double ret = Operate(num1, op, num2);

                opnd.push(ret);
                break;
            }
        }
    }//end of while

    //操作数栈的唯一元素即为计算结果
    return opnd.top();
}


int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        char str[1000];
    scanf("%s",str);
   // strcat(str,"#");
    string f;
    f=str;
    //cout<<atof(f.c_str())<<endl;
    printf("%.2lf\n",CaculateExpression(f));

    }
    return 0;
}


你可能感兴趣的:(ACM--表达式求值实现)