表達式求值

/*表達式求值
時間限制: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 <stdio.h>
#include <string.h>
#include <math.h>
#include <stack>
using namespace std;
stack<char> csta;//字符棧 
stack<double> dsta;//數據棧
char s[1010];
int main()
{
    int n;
    scanf("%d",&n); 
    while(n--)
    {
        scanf("%s",&s[1]);
        int len=strlen(&s[1]);
        s[0]='(';
        s[len]=')'; //'='改爲')' 
        for(int i=0;i<=len;i++)
        {
            if(s[i]=='(')//左括號先壓入 
                csta.push(s[i]);
            else if(s[i]>='0' && s[i]<='9')
            {
                double t=0;
                int b=0;
                while(s[i]>='0' && s[i]<='9' || s[i]=='.')
                {
                    if(s[i]=='.')   //記錄小數點位置 
                        b=i;
                    else
                        t=t*10+(s[i]-'0');  //轉成具體實數,小數乘10化整數 
                    i++;
                }
                i--;
                if(b!=0)
                    t/=pow(10,i-b);  //如果有小數點轉成具體實數
                dsta.push(t);
            }
            else if(s[i]=='+' || s[i]=='-') //先判斷後一級s[i]中的符號 
            {
                double a,b,c;

                while(csta.top()!='(')    //在判斷字符棧中的符號 
                {
                    a = dsta.top(); dsta.pop(); //將實數取出棧,彈出棧中的數據 
                    b = dsta.top(); dsta.pop();
                    switch(csta.top())   //後一級運算符是加減的話,前一級運算符不論爲什麼都是先運算 
                    {
                        case '+':c=a+b;break;
                        case '-':c=b-a;break;
                        case '*':c=b*a;break;
                        case '/':c=b/a;break;
                    }
                    dsta.push(c);  //將運算結果壓進棧
                    csta.pop();  //彈出運算後的運算符 
                }
                csta.push(s[i]);
            }
            else if(s[i]=='*' || s[i]=='/')   //先判斷後一級s[i]中的符號 
            {
                double a,b,c;
                if(csta.top()=='*' || csta.top()=='/')  //後一級運算符是 * / 的話,前一級也需要是 * / 才能先運算前一級 
                {
                    a = dsta.top(); dsta.pop();
                    b = dsta.top(); dsta.pop();
                    switch(csta.top())
                    {
                        case '*':c=b*a;break;
                        case '/':c=b/a;break;
                    }
                    dsta.push(c);//將運算結果壓進棧
                    csta.pop();//彈出運算後的運算符 
                }
                csta.push(s[i]);
            }
            else if(s[i]==')')//後一級運算符是 ) 的話,把()裏的結果運算出來 
            {
                double a,b,c;
                while(csta.top()!='(')
                {
                    a = dsta.top(); dsta.pop();
                    b = dsta.top(); dsta.pop();
                    switch(csta.top())
                    {
                        case '+':c=a+b;break;
                        case '-':c=b-a;break;
                        case '*':c=b*a;break;
                        case '/':c=b/a;break;
                    }
                    dsta.push(c); //將運算結果壓進棧
                    csta.pop();  //彈出運算後的運算符
                }
                csta.pop();  //彈出棧中的'(' 
            }
        }
        printf("%.2lf\n",dsta.top()); //輸出運算後的運算符
        dsta.pop();  //彈出棧中的結果 
    }
    return 0;
}
發佈了33 篇原創文章 · 獲贊 1 · 訪問量 9668
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章