表達式求值

思路:通過逆波蘭表達式求值的方法進行求解,可以有效的解救括號問題,因爲後綴式不需要用括號來確定優先級。

解救方案:

1、中綴式轉爲後綴式

(1)

(2) 算法實現

(a) 定義一個空棧s,和一個string數組suffix

(b)對中綴表達式每個字符進行逐個接收。

(c)如果得到的是數字或者小數點,直接按順序存到suffix內

(d)如果得到的是‘(’,壓入棧中。

(e)如果得到的是‘)’,棧頂出棧存到suffix內,直至棧頂元素爲‘)’,然後棧頂出棧,這一步可以解決小括號的問題。

 (f)如果得到的是運算符,則將此與棧頂元素進行比較,如果優先級小於棧頂元素,則將棧頂元素存到suffix中,並且出棧,然後繼續將棧頂元素與該運算符比較,直至該運算符大於棧頂元素,則將其入棧。

(g)遍歷結束後,將棧內元素出棧,存到suffix內。至此,suffix就是按照後綴式的順序存儲的了。

2、後綴式運算

(1)依照從左到右的順序讀取suffix,如果得到的是操作數或者‘.’,則將其讀取完整後處理爲數字格式入棧,如果是運算符,則進行計算,計算該運算符棧頂的兩個元素,將該兩個棧頂元素依次出棧,新得的結果入棧。

(2)讀取結束後,棧底等於棧頂且爲最後運算結果,則運算正確。

code:

#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
int weight(char a) // 運算符權重
{
    if(a == '+' || a == '-')
        return 1;
    else if(a == '*' || a == '/')
        return 2;
    else
        return 0;
}
int midtosuffix(string &mids,string &suffixs) //中綴式轉後綴式
{
    stack<char > s; //用來處理括號問題
    s.push('#');

    int i = 0;
    while(i < mids.length()-1)
    {
        if(mids[i] == '(')
        {
            s.push(mids[i]);
            i++;
        }
        else if(mids[i] == ')')
        {
            while(s.top() != '(')
            {
                suffixs += s.top();
                suffixs += ' ';
                s.pop();
            }
            s.pop();
            i++;
        }
        else if(mids[i] == '+' || mids[i] == '-' || mids[i] == '*' || mids[i] == '/')
        {
            while(weight(s.top()) >= weight(mids[i]))
            {
                suffixs += s.top();
                suffixs += ' ';
                s.pop();
            }
            s.push(mids[i]);
            i++;
        }
        else
        {
            while(mids[i] >= '0' && mids[i] <= '9' || mids[i] == '.')
            {
               suffixs += mids[i++];
            }
            suffixs += ' ';
        }
    }

    while(s.top() != '#')
    {
        suffixs += s.top();
        suffixs += ' ';
        s.pop();
    }
}
double cal(string suffixs)//後綴表達式的運算
{
    stack<double> s;
    int i = 0;
    double x,y;
    while(i < suffixs.length())
    {
        if(suffixs[i] == ' ')
        {
            i++;
            continue;
        }
        if(suffixs[i] == '+')
        {
            x = s.top();
            s.pop();
            x += s.top();
            s.pop();
            i++;
        }
        else if(suffixs[i] == '-')
        {
            x = s.top();
            s.pop();
            x = s.top() - x;
            s.pop();
            i++;
        }
        else if(suffixs[i] == '*')
        {
            x = s.top();
            s.pop();
            x *= s.top();
            s.pop();
            i++;
        }
        else if(suffixs[i] == '/')
        {
            x = s.top();
            s.pop();
            x = s.top()/x;
            s.pop();
            i++;
        }
        else
        {
            x = 0;
            while(suffixs[i] >= '0' && suffixs[i] <= '9')
            {
                x *= 10;
                x += suffixs[i]-'0';
                i++;
            }
            if(suffixs[i] == '.')
            {
                y = 0;
                double k = 10.00;
                i++;
                while(suffixs[i] >= '0' && suffixs[i] <= '9')
                {
                    y += (suffixs[i]-'0')/k;
                    k *= 10.00;
                    i++;
                }
                 x += y;
            }
        }
        s.push(x);
    }
    return s.top();//返回運算結果
}
int main()
{
    int n;
    scanf("%d",&n);
    string mids,suffixs;
    while(n--)
    {
        cin>>mids;
        suffixs = "";
        midtosuffix(mids,suffixs);
        cout<<suffixs<<" ="<<endl;
        //printf("%.2f\n",cal(suffixs));
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章