中綴表達式轉後綴表達式
依舊利用棧這種數據結構,本文只是以+、-、*、/、()幾個運算符爲例,有興趣的小夥伴可以自己拓展。
如何將a + b * c + ( d * e + f ) * g形式的中綴表達式轉換成後綴表達式呢?
先上正確答案,abc*+de*f+g*+。
步驟如下:
· 建立一個空棧;
· 遍歷字符串。當讀到操作數時,直接輸出;
· 當讀到運算符時:
a 若爲 ‘(‘,入棧;
b 若爲 ‘)’,則依次把棧中的的運算符加入後綴表達式中,直到出現’(‘,從棧中刪除’(’ ;
c 若爲除括號外的其他運算符, 當其優先級高於除’(‘以外的棧頂運算符時,直接入棧。
d 否則,依次彈出比當前處理的運算符優先級高和優先級相等的運算符,直到一個比它優先級低的或者遇到了一個左括號爲止。
e 遍歷結束時,棧中的所有運算符出棧;
那廢話不多說,直接上代碼。第一個函數int sortOperator(char c)主要是給運算符規定優先順序,方便後續判斷,可以看出如果想添加運算符種類的話,在這個函數擴展也很方便;第二個函數void infixToPostfix(string expression)就是實現轉換的函數了。
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int sortOperator(char c) {
switch (c)
{
case ')':
return 0;
case '*':
return 1;
case '/':
return 1;
case '+':
return 2;
case '-':
return 2;
case '(':
return 3;
default:
return -1;
}
}
void infixToPostfix(string expression){
stack<char> s;
for (int i = 0; i < expression.length();i++) {
//字母代表操作數,直接輸出
if (expression.at(i) >= 'a' && expression.at(i) <= 'z') {
cout << expression.at(i) << "";
}
//去除空格
else if (expression.at(i) == ' ') {}
else
switch (expression.at(i)){
//左括號直接入棧
case '(':
s.push(expression.at(i));
break;
//同級運算符寫一種就可以,因爲sortOperator返回值相同,這裏未做省略
//這裏還要注意sortOperator的返回值和實際運算優先級相反,
//也可調整爲和實際運算優先級相同,方便理解。
case'*':
//棧非空,且棧頂運算符優先級高於或等於當前運算符,出棧並輸出,直到棧頂運算符
//優先級低於當前運算符,該運算符入棧
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('*')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case '/':
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('/')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case '+':
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('+')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case '-':
while (!s.empty() &&
sortOperator(s.top()) <= sortOperator('-')) {
cout << s.top();
s.pop();
}
s.push(expression.at(i));
break;
case ')':
//遇到右括號,一直進行出棧操作並輸出,直到遇到左括號結束循環,再將左括號
//出棧,且不輸出
while (!s.empty() && s.top() != '(')
{
cout << s.top() << "";
s.pop();
}
s.pop();
break;
default:
break;
}
}
//遍歷表達式後,棧內所有操作符依次出棧並輸出。
while (!s.empty())
{
cout << s.top() << "";
s.pop();
}
cout << endl;
}
測試代碼如下,
int main(int argc, char* argv[])
{
cout << "input expression" << endl;
string line;
getline(cin, line);
infixToPostfix(line);
system("pause");
return 0;
}
有興趣的小夥伴,可以嘗試多添加幾種運算符,^, ! 等等。