思路:通過逆波蘭表達式求值的方法進行求解,可以有效的解救括號問題,因爲後綴式不需要用括號來確定優先級。
解救方案:
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));
}
}