前言
這兩天接到個活兒,是要用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;
}
}
歡迎交流。代碼完成倉促,如有錯誤還望指正。