中缀表达式转后缀表达式遵循如下原则:ios
1.遇到操做数,直接输出;
2.栈为空时,遇到运算符,入栈;
3.遇到左括号,将其入栈;
4.遇到右括号,执行出栈操做,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;
5.遇到其余运算符’+”-”*”/’时,弹出全部优先级大于或等于该运算符的栈顶元素,而后将该运算符入栈;
6.最终将栈中的元素依次出栈,输出。
通过上面的步骤,获得的输出既是转换获得的后缀表达式。
举例:a+b*c+(d*e+f)g ———> abc*+de*f+g*+数组
由于比较懒,而恰好在网上看到画的还不错的图,因此就直接贴过来了哦。但愿做者不要怪罪哦。。。
遇到a,直接输出:app
遇到+,此时栈为空,入栈:
函数
遇到b,直接输出:
遇到*,优先级大于栈顶符号优先级,入栈:
spa
遇到c,输出:
到+,目前站内的与+优先级都大于或等于它,所以将栈内的,+依次弹出而且输出,而且将遇到的这个+入栈:
遇到(,将其入栈:
3d
遇到d,直接输出:
遇到*
,因为的优先级高于处在栈中的(,所以入栈:
遇到e,直接输出:
遇到+,栈顶的优先级高于+,可是栈内的(低于+,将出栈输出,+入栈:code
遇到f,直接输出:
遇到),弹出栈顶元素而且输出,直到弹出(才结束,在这里也就是弹出+输出,弹出(不输出:
遇到*,
优先级高于栈顶+,将*入栈
遇到g,直接输出: :
此时已经没有新的字符了,依次出栈并输出操做直到栈为空:
orm
/* C++实现中缀表达式转后缀表达式并求值 */ #include <iostream> using namespace std; const int MaxLen = 100; //类的定义 class zh { private: int n; // 结果 char str[MaxLen]; // 存中缀表达式 char exp[MaxLen]; // 存后缀表达式 char st[MaxLen]; // 临时栈 public: zh() // 构造函数 - 初始化中缀表达式 { cout << "请输入中缀表达式:"; cin >> str; cout << endl; } bool trans(); // 中缀转后缀,并将后缀存入exp中 bool CompValue(); // 利用后缀求值 void disp_exp(); // 输出后缀表达式 int Get_n() { return n ;} // return 结果 } ; //中缀转后缀,并将后缀存入exp中 bool zh::trans() { char ch; int i = 0, t = 0, top = -1; //t - exp下标, top - st的下标, i - str的下标 while( (ch = str[i++]) != '\0' ) { if( ch >= '0' && ch <= '9' ) //判断为数字 { exp[t] = ch; t++; while( (ch = str[i++]) != '\0' && ch >= '0' && ch <= '9' ) { exp[t] = ch; t++; } i--; exp[t] = '#'; // 数字结束标识符 t++; } else if( ch == '(' ) //左括号入栈 { top++; st[top] = ch; } else if( ch == ')' ) // 右括号输出栈中左括号之前的全部运算符 { while( st[top] != '(' ) // 输出栈中左括号之前的全部运算符 { exp[t] = st[top]; top--; t++; } top--; //与之匹配的左括号弹出 } else if( ch == '+' || ch == '-' ) //当扫描到运算符时,从临时栈中弹出优先级大于等于当前运算符的 { //运算符,注:圆括号的优先级最高 while( top >= 0 && st[top] != '(' ) { while( st[top] == '*' || st[top] == '/' || st[top] == '+' || st[top] == '-' ) { exp[t] = st[top]; top--; t++; } } top++; st[top] = ch; } else if( ch == '*' || ch == '/' ) // 若为运算符 * 或 / { while( top >= 0 && st[top] != '(' ) // 弹出st栈顶位置的 * 或 / { while( st[top] == '*' || st[top] == '/' ) { exp[t] = st[top]; top--; t++; } } top++; st[top] = ch; } } while( top >= 0 ) // 当扫描完运算式时,将此时栈中的全部运算符弹出 { exp[t] = st[top]; t++; top--; } exp[t] = '\0'; // exp - 按后缀顺序存储运算表达式 return true; } //利用后缀表达式计算 //从左向右扫描 exp数组,遇到操做数入栈、遇到运算符弹出操做数 bool zh::CompValue() { int d; // 数字字符转数字 char ch; int t = 0, top = -1; while( (ch = exp[t++]) != '\0' ) { if( ch >= '0' && ch <= '9' ) //为数字字符时转换为数字并入栈 { d = 0; do { d = 10*d + ch-'0'; } while( (ch = exp[t++]) != '#' ); top++; st[top] = d; //数字进栈 } else //为运算符时,退栈 - 计算 - 在将结果入栈 { switch( ch ) //为运算符时则,弹出两个操做数,先弹出的为右操做数、后为左,并将计算结果入栈 { case '+': st[top-1] = st[top-1] + st[top]; break; case '-': st[top-1] = st[top-1] - st[top]; break; case '*': st[top-1] = st[top-1] * st[top]; break; case '/': if( st[top] != 0 ) st[top-1] = st[top-1] / st[top]; //除数不能为 0 else { return 0; //除0错误 } break; } top--; } } n = st[top]; //表达式终止时,栈中的值即为计算结果 return true; } //输出后缀表达式 void zh::disp_exp() { cout << "后缀表达式为"; cout << exp << endl; cout << endl; } int main() { zh A; if( A.trans() == 0 ) cout << "中缀表达式不正确" << endl; else { A.disp_exp(); if( A.CompValue() == 1 ) cout << "计算结果: " << A.Get_n() << endl; else cout << "计算错误" << endl; } return 0; }