转载:http://blog.csdn.net/chhj0103121429/article/details/40925555
对于给定的一个的表达式: a * b + c * d. 我们称之为infix表达式. 这是我们看得比较习惯的方式.
但是编译器这样看不好, 不像人可以自动辨别优先级. 所以出现了 prefix 和 postfix 两种表达式, 其中prefix是操作符在前, postfix是操作符在后.
手工转换非常简单, 只要给所有运算添上括号, 然后将括号中的操作符移动到括号外, 最后移除括号就能得出 postfix 或者 prefix 表达式.
如转换为prefix: a * b + c * d → ((a * b) + (c * d)) → + ( * (a b) * (c d)) → + * a b * c d
转换为postfix: a * b + c * d → ((a * b) + (c * d)) → ((a b) * (c d) * ) + → a b * c d * +
程序转换:
转prefix:
1.存两个堆栈, 一个存放操作数, 一个存放运算符
2.由于要转换为prefix, 运算符在操作数前, 所以扫描从中缀表达式的右往左扫描.
3.如果是操作数, 则直接压进操作数栈中
4.如果是运算符, 分以下情况:
a. 运算符堆栈为空, 或者运算符栈顶元素为')', 则直接将运算符压进栈
b. 运算符如果是'(', 则将运算符栈中的元素都压进去操作数栈中并将其弹出运算符栈, 直到遇到')'为止
c. 运算操作符是'+' '-' '*' '/' 之一的时候, 将其与运算符栈顶元素作比较,如果优先级相同, 或者栈顶的优先级较小, 则将运算符压入栈中.
否则, 将栈顶元素弹出并压入操作数栈中, 然后继续比较栈顶, 直到运算符被压入栈.
5.扫描完一遍后, 将运算符堆栈剩余的元素都压入操作数栈中.
6.将操作数栈从栈顶到栈底输出就是prefix.
转postfix:
1.一个存放结果的输出队列, 一个存放运算符的堆栈
2.由于要转换为postfix, 运算符在操作数后, 所以扫描从中缀表达式的左往右扫描.
3.如果是操作数, 则直接压进输出队列中
4.如果是运算符, 分以下情况:
a. 运算符堆栈为空, 或者运算符栈顶元素为'(', 则直接将运算符压进栈
b. 运算符如果是')', 则将运算符栈中的元素都压进去输出队列中并将其弹出运算符栈, 直到遇到'('为止
c. 运算操作符是'+' '-' '*' '/' 之一的时候, 将其与运算符栈顶元素作比较,如果栈顶的优先级较小, 则将运算符压入栈中.
否则, 将栈顶元素弹出并压入输出队列中, 然后继续比较栈顶, 直到运算符被压入栈.
5.扫描完一遍后, 将运算符堆栈剩余的元素都压入输出队列中.
6.将队列输出就是postfix.
计算prefix表达式的值:
1. 用一个堆栈存放中间结果.
2.从右往左扫描前缀表达式.
a. 如果遇到操作数, 直接压进栈
b. 遇到运算符, 将栈顶元素弹出置于左操作数, 再弹出一个栈顶元素置于右操作数. 然后进行运算:"左操作数 运算符 右操作数". 生成结果压入栈中
3.扫描完后, 将栈中的结果输出便是答案
计算postfix表达式的值:
1. 用一个堆栈存放中间结果.
2.从左往右扫描后缀表达式.
a. 如果遇到操作数, 直接压进栈
b. 遇到运算符, 将栈顶元素弹出置于右操作数, 再弹出一个栈顶元素置于左操作数. 然后进行运算:"左操作数 运算符 右操作数". 生成结果压入栈中
3.扫描完后, 将栈中的结果输出便是答案