前綴、中綴與後綴表達式的互相轉換

前言

這兩天接到個活兒,是要用c++完成中綴表達式和後綴表達式的相互轉換。雖然在大二數據結構課的時候上過有關內容,現在卻忘得差不多了。而且由於並沒有系統的上過c++,熟悉c++的各種寫法和格式還是頗花了些時間的。
下面簡單記錄下。

知識儲備

有關於前綴、中綴、後綴表達式的基本定義、中綴轉前綴方法、中綴轉後綴方法,在百度上找到的比較詳細嚴謹的博文在此:
表達式的轉換
看完基本就沒什麼問題了,這塊也不難。不過這位兄弟沒有討論後(前)綴轉中綴表達式的情況。百度了很久,只找到很多像上述博文中綴轉前(後)綴的,沒有找到後(前)綴轉中綴的。下面以後綴轉中綴爲例子,簡單說下思路。

後綴轉中綴表達式

直接放c++的代碼:

string temp1 = stk[top--];
string temp2 = stk[top--];
string temp3 = "(";
switch (buf[i]){
case '+':temp3 += temp2; temp3 += '+'; temp3 += temp1; temp3 += ')'; stk[++top] = temp3; break;
case '-':temp3 += temp2; temp3 += '-'; temp3 += temp1; temp3 += ')'; stk[++top] = temp3; break;
case '*':temp2 += '*'; temp2 += temp1; stk[++top] = temp2; break;
case '/':temp2 += '/'; temp2 += temp1; stk[++top] = temp2; break;
}

思路如上,可以說是一目瞭然了,逆向變回去就可以了。
要注意的是+ -這些低級運算符要加括號。這種方法會造成有多餘括號產生,例如11+會轉換成(1+1),不過無傷大雅。

代碼

上代碼。註釋較爲簡單,需要結合代碼思考理解。

/*
Users can choose mode1 or mode2 to transform their expression and get the final result.
If users enter a number which is neither 1 nor 2, the system will prompt you to enter again.
Each input value should be between 0 and 9.
The input expression can only include number + - * and /
*/

#include <iostream>
#include<string>
#include <stack>
using namespace std;
int pri[1111];
class Expression{
public:
	string inToPost(){
		//define priority here
		pri['+'] = pri['-'] = 1;
		pri['*'] = pri['/'] = 2;
		pri['('] = pri[')'] = 0;
		//store the input temporarily
		char buf[100];
		stack<char> stk;
		int length = infix.copy(buf, 100);
		buf[length] = '\0';
		for (int i = 0; i < length; i++){
			//the operation towards number
			if (buf[i]>47 && buf[i] < 58){
				postfix += buf[i];
			}
			//the operation towards (
			else if (buf[i] == '('){
				stk.push(buf[i]);
			}
			//the operation towards )
			else if (buf[i] == ')'){
				while (stk.top() != '('){
					postfix += stk.top();
					stk.pop();
				}
				stk.pop();
			}
			//the operation towards + - * /
			else{
				if (!stk.empty()){
					while (pri[stk.top()] >= pri[buf[i]]) {
						postfix += stk.top();
						stk.pop();
						if (stk.empty())break;
					}
				}
				stk.push(buf[i]);
			}

		}
		//put the remains into stack
		while (!stk.empty()) {
			postfix += stk.top();
			stk.pop();
		}
		return postfix;
	};
	string postToIn(){
		pri['+'] = pri['-'] = 1;//define priority
		pri['*'] = pri['/'] = 2;
		pri['('] = pri[')'] = 0;
		//store the input temporarily
		char buf[100];
		string stk[100];
		int top = -1;
		int length = postfix.copy(buf, 100);
		buf[length] = '\0';
		for (int i = 0; i < length; i++){
			//the operation towards number
			if (buf[i]>47 && buf[i] < 58){
				stk[++top] = buf[i];
			}
			//the operation towards + - * /
			else{
				string temp1 = stk[top--];
				string temp2 = stk[top--];
				string temp3 = "(";
				switch (buf[i]){
				case '+':temp3 += temp2; temp3 += '+'; temp3 += temp1; temp3 += ')'; stk[++top] = temp3; break;
				case '-':temp3 += temp2; temp3 += '-'; temp3 += temp1; temp3 += ')'; stk[++top] = temp3; break;
				case '*':temp2 += '*'; temp2 += temp1; stk[++top] = temp2; break;
				case '/':temp2 += '/'; temp2 += temp1; stk[++top] = temp2; break;
				}
			}

		}
		infix = stk[0];
		top--;//initialize the stack
		return infix;
	};
	double evaluate(){
		pri['+'] = pri['-'] = 1;//define priority
		pri['*'] = pri['/'] = 2;
		pri['('] = pri[')'] = 0;
		char buf[100];
		stack<double> stk;
		double temp1, temp2;
		int length = postfix.copy(buf, 100);
		buf[length] = '\0';
		for (int i = 0; i < length; i++){
			//the operation towards number
			if (buf[i]>47 && buf[i] < 58){
				stk.push((buf[i] - 48));
			}
			//the operation towards + - * /
			else{
				temp1 = stk.top();
				stk.pop();
				temp2 = stk.top();
				stk.pop();
				switch (buf[i]){
				case '+':stk.push(temp2 + temp1); break;
				case '-':stk.push(temp2 - temp1); break;
				case '*':stk.push(temp2 * temp1); break;
				case '/':stk.push(temp2 / temp1); break;
				}
			}
		}
		double result = stk.top();
		stk.pop();//initialize stack
		return result;
	}
	//constructor
	Expression(string input, int direction){
		if (direction == 1) infix = input;
		else if (direction == 2) postfix = input;
	};
private:
	string infix;
	string postfix;
};
int main(){
	int direction;
	string input;
	while (1){
		cout << "Please confirm your expression type." << endl;
		cout << "If you choose the infix one, enter 1" << endl;
		cout << "If you choose the postfix one, enter 2" << endl;
		cout << "Enter 0 to quit" << endl;
		cin >> direction;
		//check the value of direction
		if (direction == 0) break;
		if (direction != 1 && direction != 2){
			cout << "Your choice is not available,please confirm again later." << endl;
			continue;
		}
		cout << "Enter your expression:" << endl;
		cin >> input;
		Expression exp(input, direction);
		if (direction == 1){
			cout << "The postfix one is: " << exp.inToPost() << endl;
		}
		else {
			cout << "The infix one is: " << exp.postToIn() << endl;
		}
		cout << "the result is: " << exp.evaluate() << endl;
	}
}

歡迎交流。代碼完成倉促,如有錯誤還望指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章