Task A1 中綴表示式轉換為逆波蘭式

YunC發表於2024-11-24

A1 表示式轉換

【題目描述PTA(資料結構與演算法題目集 7-20)
算術表示式有字首表示法、中綴表示法和字尾表示法等形式。日常使用的算術表示式是採用中綴表
示法,即二元運算子位於兩個運算數中間。請設計程式將中綴表示式轉換為字尾表示式。
輸入格式
輸入在一行中給出不含空格的中綴表示式,可包含+、-、*、/以及左右括號(),表示式不超過 20 個
字元。
輸出格式
在一行中輸出轉換後的字尾表示式,要求不同物件(運算數、運算子號)之間以空格分隔,但結尾
不得有多餘空格。
輸入樣例

2+3*(7-4)+8/4

輸出樣例

2 3 7 4 - * + 8 4 / +

問題分析
算術表示式有中綴表示式,字首表示式和字尾表示式等形式。將中綴表示式轉化為字尾表示式(也稱逆波蘭式表示法)是一種常見的計算問題,我們可以使用棧資料結構來解決。下面是演算法步驟:

  1. 初始化一個空的運算元棧,用於存放運算子。
  2. 從左到右掃描中綴表示式的每一個元素。
  3. 如果遇到的是運算元,數字,則直接新增到輸出佇列的末尾。
  4. 如果遇到運算子+-*/,則做以下處理:
    • 將棧頂元素彈出並新增到輸出佇列,知道棧頂的運算子優先順序低於或等於當前運算子的優先順序。
    • 將當前運算子壓入棧中。
  5. 如果遇到左括號,壓入棧中。
  6. 如果遇到右括號,則從棧中彈出運算子並新增到輸出佇列,知道遇到左括號為止,此時,將左括號從棧中移除,但不新增到輸出佇列。
  7. 當所有表示式的所有元素都處理完了後,將棧中剩餘運算子一次彈出並新增到輸出佇列,直到為空。

根據上述演算法,我們可以寫出多條件語句程式碼:

#include<iostream>
using namespace std;

// 運算子優先順序
int priority(char op) {
	if (op == '+' || op == '-') return 1;
	if (op == '*' || op == '/') return 2;
	return 0; // 其他情況比如括號
}

// 判斷是否為運算子
bool isOperator(char ch) {
	return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}

class Stack { // 棧類
private:
	int top;
public:
	char data[20]; //不超過20個字元
	Stack() { top = -1; }//建構函式
	bool isEmpty() { return top == -1; }
	void push(char ch) { data[++top] = ch; }
	char pop() { return data[top--]; }
	char Top() { return data[top]; }
};


string getsuffix(string& infix) {
	string suffix;
	Stack s;
	// 遍歷中綴表示式,如果是數字,加入字尾表示式;
	// 如果是運算子,判斷優先順序,如果棧中元素大於或等於當前運算子,彈出棧頂元素,否則壓入棧;
	// 如果遇到右括號,彈出棧中元素,直到遇到左括號,左括號不加入字尾表示式。
	for (char ch : infix) 
	{
		if (isalnum(ch)) { //數字或字母
			suffix += ch;
			suffix += ' ';
		}
		else if (ch == '(') { //左括號
			s.push(ch);
		} 
		else if (ch == ')') { //右括號
			while (!s.isEmpty() && s.Top() != '(') {
                suffix += s.pop();
                suffix += ' ';
			}
			s.pop();//彈出左括號,不加入字尾表示式
		}
		else if (isOperator(ch)) {
			//彈出大於等於當前優先順序的運算子
			while (!s.isEmpty() && priority(s.Top()) >= priority(ch)) {
                suffix += s.pop();
                suffix += ' ';
			}
            s.push(ch);//壓入當前運算子
		}
	}
	//將剩餘的運算子加入字尾表示式
	while (!s.isEmpty()) {
		suffix += s.pop();
        suffix += ' ';
	}
	//去掉最後一個空格
	if (!suffix.empty()) {
		suffix.pop_back();
	}

	return suffix;
}

int main() {
	cout << "請輸入中綴算術表示式:" << endl;
	string infix;
	cin >> infix;
	cout << "字尾表示式為:" << endl << getsuffix(infix) ;
	return 0;
}

執行結果如下:

相關文章