栈的应用——四则运算表达式求值

1:后缀表示法定义
所有的符号都是在要运算数字的后面出现。
如:

9+(3-1)*3+10/2的后缀表示法应该是9 3 1-3*+10 2/+

2:后缀表达式计算结果
规则:从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到是符号,就将处于栈顶的两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

以9 3 1-3*+10 2/+为例
1:初始化一个空栈。
2:表达式中前三个都是数字,所以9、3、1进栈。
    栈:9 3 1
3:遇到符号“-”,所以将栈顶的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈。
    栈:9 2
4:数字3进栈。
    栈:9 2 3
5:遇到符号“*”,所以将栈顶的3和2出栈,并运算3*2得到6,再将6进栈。
    栈:9 6
6:遇到符号“+”,所以将栈顶的6和9出栈,并运算6+9得到15,再将15进栈。
    栈:15
7:数字10和2进栈。
    栈:15 10 2
8:遇到符号“/”,所以将栈顶的2和10出栈,并运算10/2得到5,再将5进栈。
    栈:15 5
9:遇到符号“+”,所以将栈顶的5和15出栈,并运算5+15得到20,再将20进栈。
    栈:20
10:运算结束,将栈顶的20出栈即为运算结果,栈变为空。

代码如下:

public int count(String[] post){
        Deque<Integer> deque=new LinkedList();
        int a,b;
        for(int i=0;i<post.length;i++){
            if(post[i]==null){
                break;
            }
            switch(post[i]){
            case "+":
                a=deque.pop();
                b=deque.pop();
                deque.push(b+a);
                break;
            case "-":
                a=deque.pop();
                b=deque.pop();
                deque.push(b-a);
                break;
            case "*":
                a=deque.pop();
                b=deque.pop();
                deque.push(b*a);
                break;
            case "/":
                a=deque.pop();
                b=deque.pop();
                deque.push(b/a);
                break;
            default: deque.push(Integer.valueOf(post[i]));
            }
        }
        return deque.pop();
    }

3:中缀表达式转后缀表达式
规则:从左到右遍历中缀表达式的每个数字和符号,如实数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。

以9+(3-1)*3+10/2为例
1:初始化一空栈。
2:遇到数字9,输出9。接着是符号“+”,进栈。 
   输出:9    栈:+   
3:遇到符号“(”,因其实左括号,还未配对,进栈。
   输出:9    栈:+,(
4:遇到数字3,输出3。接着是符号“-”,进栈。
   输出:9 3  栈:+,(,-
5:遇到数字1,输出1。接着是符号“)”,此时,我们要匹配此前的“(”,所以栈顶一次出战,并输出,直到“(”出栈为止。
   输出:9 3 1 -   栈:+
6:遇到符号“*”,因为优先级高于栈顶符号为“+”,因此“*”进栈。
   输出:9 3 1 -   栈:+,*
7:遇到数字3,输出3。接着是符号“+”,优先级低于栈顶符号“*”,因此栈中元素出栈并输出(没有比“+”号更低的优先级,所以全部出栈),然后符号“+”进栈。
   输出:9 3 1 - 3 * +  栈:+
8:遇到数字10,输出10。接着是符号“/”,优先级高于栈顶符号“+”,因此“/”进栈。
   输出:9 3 1 - 3 * + 10  栈:+,/
9:遇到数字2,输出2。因已经到最后,所以栈中符号全部出栈输出。
   输出:9 3 1 - 3 * + 10 2 / +          

代码如下:

 public int precede(String x,String y){
         int a=0,b=0;
         switch(x){
         case "(":a=0;break;    //当“(”在栈内时,其优先级最低,直到遇到“)”才会出栈。
         case "+":
         case "-":a=1;break;
         case "*":
         case "/":a=2;break;
         }
         switch(y){
         case "(":b=3;break;    //当遇到符号“(”时,其优先级最高,必须进栈。
         case "+":
         case "-":b=1;break;
         case "*":
         case "/":b=2;break;
         }
         return a>=b?1:0;
     }
     public String[] mid_post(String[] mid){
         Deque<String> deque=new LinkedList();
         StringBuilder sb=new StringBuilder();
         for(int i=0;i<mid.length;i++){
             switch(mid[i]){
             case ")":
                 while(!deque.isEmpty()&&!deque.peek().equals("(")){
                     sb.append(deque.pop());
                     sb.append(" ");
                 }
                 deque.pop();  //必须将符号“(”出栈
                 break;
             case "+":
             case "-":
             case "*":
             case "/":
             case "(":
                 while(!deque.isEmpty()&&precede(deque.peek(),mid[i])>0){
                     sb.append(deque.pop());
                     sb.append(" ");
                 }
                 deque.push(mid[i]);
                 break;
            default:
                sb.append(mid[i]); 
                sb.append(" ");
             }
         }
         while(!deque.isEmpty()){
             sb.append(deque.pop());
             sb.append(" ");
         }
         return sb.toString().split(" ");
     }

4:中缀表达式转后缀表达式的一般方法

9+(3-1*3+10/2为例
1:根据优先级,添加括号
((9+((3-1*3))+(10/2))
2:将符号移到对应的右括号右边
((9((3 1)-3*)+(10 2)/)+
3:将括号去掉后即得后缀表达式
9 3 1-3*+10 2/+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值