中綴表達式轉後綴表達式
1 基本概念
在計算機中表達式有三種,前綴表達式(波蘭式),中綴表達式,後綴表達式(逆波蘭式)。
如表達式:a+b*(c-d)-e/f
前綴表達式:-+a*b-cd/ef
中綴表達式:a+b*(c-d)-e/f
後綴表達式:abcd-*+ef/-
1.1 特點與利弊
中綴表達式的括號必不可少,它的優點是符合我們人類的書寫和讀取習慣,但缺點是它不方便計算機處理。
前綴和後綴表達式的缺點是不是我們閱讀的習慣,但是它們卻便於計算機的處理。比如針對後綴表達式來說,它是把操作數一直壓入棧中,然後遇到一個操作符的時候,就從棧中取出兩個數進行計算,再把得到的結果壓入棧中。因此前綴和後綴是非常方便計算機處理的。
現在考慮把中綴表達式轉化爲後綴表達式或者是從輸入的中綴表達式轉換爲後綴表達式。
2 轉換原理
原理不難,我們遇到遇到操作數的時候直接輸出,當遇到操作符(包括‘(’,‘+’,‘-’,‘*’,‘/’)的時候,我們需要把符號壓入到棧中,
2.1 當遇到‘)’的時候:
我們需要依次從棧頂彈出符號,直到遇到‘(’,並且要將‘(’彈出。如:(a*(b+c)),棧中的是(*(+,當遇到‘)’的時候,我們要彈出‘+’,‘(’。
2.2 當遇到‘(’的時候
此時沒什麼要說的,直接壓棧。
2.3 當遇到‘+’,‘-’,‘*’,‘/’的時候:
我們要把棧頂元素的符號的優先級跟輸入的符號的優先級進行對比,如果棧頂優先級高的話,我們就要把棧頂元素依次彈出,直到棧頂的優先級低於輸入的優先級或者棧空。
如:a+b+c+d,跟a+b*c+d得到的符號順序就不一樣,原因就是這個優先級的問題。
2.4 當遇到操作數的時候:
毫無疑問,直接輸出
3 程序
#include <iostream>
#include <stack>
using namespace std;
void changePosfix();
int priorty(charch);
void main()
{
changePosfix();
}
void changePosfix()
{
stack<char>chStack;
charch;
bool bg= false;
while(ch = getchar() )
{
switch(ch)
{
case'(':
chStack.push(ch);
break;
case')':
while( chStack.top() != '(')
{
cout<<chStack.top();
chStack.pop();
}
chStack.pop();
break;
case'+':
case'-':
case'*':
case'/':
//for example a+b*c+d,when meet last
while( !chStack.empty() &&priorty(chStack.top() )>=priorty(ch) )
{
cout<<chStack.top();
chStack.pop();
}
// at last put ch in the end
chStack.push(ch);
break;
case'\n':
while( !chStack.empty() )
{
cout<<chStack.top();
chStack.pop();
}
bg = true;
break;
default:
cout<<ch;
}
if(bg )
break;
}
}
inline int priorty(char ch)
{
switch(ch)
{
case '+':
case '-':
return1;
case '*':
case'/':
return2;
default:
return0;
}
}