1、逆波蘭表示式簡介
假定給定乙個只 包含 加、減、乘、除,和括號的算術表示式,你怎麼編寫程式計算出其結果。問題是:在表示式中,括號,以及括號的多層巢狀 的使用,運算子的優先順序不同等因素,使得乙個算術表示式在計算時,運算順序往往因表示式的內容而定,不具規律性。 這樣很難編寫出統一的計算指令。
使用逆波蘭演算法可以輕鬆解決。他的核心思想是將普通的中綴表示式轉換為字尾表示式。
轉換為字尾表示式的好處是:
2、將中綴表示式轉換成字尾式(逆波蘭表示式)
1. 從左到右讀進中序表示式的每個字元。
2. 如果讀到的字元為運算元,則直接輸出到字尾表示式中。
3. 如果遇到「)」,則彈出棧內的運算子,直到彈出到乙個「(」,兩者相互抵消。
4. 「(」的優先順序在棧內比任何運算子都小,任何運算子都可以壓過它,不過在棧外卻是優先順序最高者。
5. 當運算子準備進入棧內時,必須和棧頂的運算子比較,如果外面的運算子優先順序高於棧頂的運算子的優先順序,則壓棧;如果優先順序低於或等於棧頂的運算子的優先順序,則彈棧。直到棧頂的運算子的優先順序低於外面的運算子優先順序或者棧為空時,再把外面的運算子壓棧。
6. 中綴表示式讀完後,如果運算子棧不為空,則將其內的運算子逐一彈出,輸出到字尾表示式中。
//比較lhs的優先順序是否不高於rhs,rhs表示棧頂的符號
bool priority(const char &lhs, const char &rhs)
//將中綴表示式轉換成字尾式(逆波蘭表示式)
string exchange(const string &str)
else//如果是符號,需要與棧頂的元素進行比較
st.pop();
}else//遇到的是其他操作符
st.push(str[i]);
}else//優先順序比棧頂元素高,壓棧}}
}}
while (!st.empty())//如果堆疊不為空,則將其中的元素全部彈出
for (auto v : vec)
res += v;
return res;
}
3、字尾表示式求值
字尾表示式具有和字首表示式類似的好處,沒有優先順序的問題。
1. 直接讀取表示式,如果遇到數字就壓棧。
2. 如果遇到運算子,就彈出兩個數進行運算,隨後再將運算結果壓棧。
//定義四則運算
int operate(int first, int second, char op)
return res;
}int calculate(string input)
else//遇到字元就彈出兩個運算元進行運算
}return st.empty() ? 0 : st.top();//最後的結果為棧頂元素
}int main(int argc, char const *argv)
棧的應用之後綴表示式求值
字尾表示式,指的是不包含括號,運算子放在兩個運算物件的後面,所有的計算按運算子出現的順序,嚴格從左向右進行 不再考慮運算子的優先規則 我們數學上採用的表示式叫中綴表示式,即將運算放在兩個運算物件中間。此外還有字尾表示式,即將運算子放在兩個運算物件的前面。下面是同乙個算術表示式的三種等價表示形式 中綴...
棧的應用之表示式求值
include include include include include include using namespace std struct stacknode 用來訪問運算子的棧 struct stacknode1 用於訪問數字的棧 typedef stacknode stack type...
棧的應用之算術表示式求值
1 2 3 4 此算術表示式由一些操作符和運算元組成。其中,操作符有 等,運算元有 1 2 3 等。對於操作符來說,其運算是有優先順序的。比如,上述表示式中,3 4應該先進行操作,將得到的結果再與2相乘。算符間的優先關係如下 運算子 根據算符間的優先關係表,使用兩個棧。乙個棧為optr,儲存運算子,...