后缀表达式

         日常算数中是将一个操作符放在两个操作数中间的比如:1+2。因为是把操作符写在操作数中间,所以这种表达法被称为中缀表达法。

         而后缀表达法,也叫做波兰逆序表达法(Reverse Polish Notation   RPN),它是由一位波兰数学家发明的,操作符跟在两个操作数后面,这样A+B 就可以表示为AB+,

A/B 表示为 AB/。

如下所示:

中缀表达式                                    后缀表达式

A+B-C                                             AB+C-

A*B/C                                              AB*C/

A+B*C                                            ABC*+

A*B+C                                            AB*C+

A*(B+C)                                         ABC+C

A*B+C*D                                       AB*CD*+

(A+B)*(C-D)                                  AB+CD-*

((A+B)*C)-D                                   AB+C*D-

A+B*(C-D/(E+F))                          ABCDEF+/-*+

       此处仅仅讨论加减乘除和括号这几种操作符,剩余的比如说乘方,根号等暂时不做讨论。

      林外除了中缀表达法还有一种前缀表达法,即操作符写在两个操作数前面,这种表达法和后缀表达法类似但是很少使用。一下主要讨论两个问题1、怎样把中缀表达式转换成后缀表达式。2、怎么计算一个后缀表达式的值。


     一、如何把一个中缀表达式转换成后缀表达式:

      在转换过程中常使用栈这种数据结构,具体的规则如下

      从左到右依次从一个中缀式中读取一个字符

      1、如果该字符为操作数,则立刻输出;

      2、如果该字符为左括号'(' 则立即将其压栈;

      3、如果该字符为一个操作符:

            3.1、如果栈为空,或者栈顶元素为左括号'(',则立即将该操作符压栈;

            3.2、如果栈顶操作符的优先级小于他自己,则立即将该操作符压栈;

            3.3、如果栈顶操作符优先级大于等于自己,则先将栈顶元素出栈,保存为临时变量,先将自己压栈,在将临时变量压栈;

    4、如果该字符为右括号'(',则依次从栈中弹出元素,直至栈为空或者弹出元素为左括号。

    5、如果表达式遍历完毕,则依次出栈,直至栈空



     以下为java代码:Infix类接收一个中缀式作为参数,输出一个后缀式,Test类为测试类

    import java.util.Stack;

public class Infix {
Stack<Character> stack;
String inputStr;
String outputStr = "";

public Infix(String inputStr) {
super();
this.inputStr = inputStr;
stack = new Stack<Character>();
train();
System.out.println("\n"+outputStr+"\n");
}

// 中缀表达式转换成后缀表达式
private void train() {
for (int i = 0; i < inputStr.length(); i++) {
System.out.print(inputStr.charAt(i));
readin(inputStr.charAt(i));
}
while(!stack.isEmpty()){
outputStr+=stack.pop();
}
}

// 依次从左到右每次读入一个字符
private void readin(char charAt) {
switch (charAt) {
// 加号拥有同样的优先级
case '+':
case '-':
addOption1(charAt);
break;
// 乘号和除号拥有同样的优先级
case '*':
case '/':
addOption2(charAt);
break;
case '(':
addOption3(charAt);
break;
case ')':
addOption4(charAt);
break;
default:
addNum(charAt);
break;
}
}

private void addNum(char charAt) {
outputStr += charAt;
}

private void addOption4(char charAt) {
while (!stack.isEmpty()&&stack.peek()!='(') {
outputStr+=stack.pop();
}
stack.pop();
}

private void addOption3(char charAt) {
stack.push(charAt);
}

private void addOption2(char charAt) {
if(stack.isEmpty()||stack.peek()=='('){
stack.push(charAt);
}else if(stack.peek()=='+'||stack.peek()=='-'){
stack.push(charAt);
}else {
Character temp = stack.pop();
stack.push(charAt);
stack.push(temp);
}
}

private void addOption1(char charAt) {
if(stack.isEmpty()||stack.peek()=='('){
stack.push(charAt);
}else if (stack.peek()=='*'||stack.peek()=='/') {
outputStr+=stack.pop();
stack.push(charAt);
}else {
Character temp = stack.pop();
stack.push(charAt);
stack.push(temp);
}
}

}






public class Test {
public static void main(String[] args) {
Infix infix = new Infix("1+2*(4-3)");
Infix infix2 = new Infix("(1+2)-(2+3)");
Infix infix3 = new Infix("a+b*c");
Infix infix4 = new Infix("a*(b+c)");
Infix infix5 = new Infix("a+b*(c-d)");
Infix infix6 = new Infix("A+B*(C-D/(E+F))");
Infix infix7 = new Infix("((A+B)*C)-D");
Infix infix8 = new Infix("(A+B)*(C-D) ");
}
}

 测试结果如下

1+2*(4-3)
1243-*+

(1+2)-(2+3)
12+23+-

a+b*c
abc*+

a*(b+c)
abc+*

a+b*(c-d)
abcd-*+

A+B*(C-D/(E+F))
ABCDEF+/-*+

((A+B)*C)-D
AB+C*D-

(A+B)*(C-D)
AB+CD- *



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值