栈的应用二--四则运算表达式求值(逆波兰表示:后缀表达式)

2 篇文章 0 订阅

栈的应用一–斐波那契(Fibonacci)数列的实现(代码)

中缀表达式,我们把平时所用的标准的四则运算表达式“9+()3-1)*3+10/2”叫做中缀表达式。
后缀表达式,所有的符号都是在要运算的数字的后面出现:9 3 1 - 3 * + 10 2 / + ;我们也叫它:逆波兰表示(Reverse Polish Notation,RPN)


将中缀表达式转换为后缀表达式:

规则:从左到右便利中缀表达式的每一个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减,若优先级相同,则看先后顺序:由于是自左向右运算所以先进展的要先与后进的)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。

后缀表达式的计算结果:

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

代码实现:

package com.sfd.use;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class RPN {

    // 保存运算符的优先级
    private static Map<Character, Integer> map = new HashMap<Character, Integer>();

    static {

        map.put('*', 2);
        map.put('/', 2);
        map.put('+', 1);
        map.put('-', 1);
        map.put(')', 3);
        map.put('(', 0);

    }

    public static void main(String[] args) {
        String string = "9+((3-15)*2)+3*3+10/2";
        // 将中缀表达式转换成后缀表达式
        String houzhui = change(string);
        System.out.println("string:" + houzhui);
        // 得到计算结果
        System.out.println(compute(houzhui));

    }

    public static double compute(String string) {
        int result = 0;
        String[] strings = string.split(" ");
        Stack<String> stack = new Stack<String>();
        String n1 = "";
        String n2 = "";
        for (String s : strings) {
            // System.out.println(s);
            if (s.matches("^\\d*$")) {
                System.out.println(s);
                stack.push(s);
            } else {
                System.out.println(s);
                // 匹配运算符字符串,进行相应的运算
                switch (s) {
                case "+":
                    n1 = stack.pop();
                    n2 = stack.pop();
                    result = Integer.parseInt(n2) + Integer.parseInt(n1);
                    break;
                case "-":
                    n1 = stack.pop();
                    n2 = stack.pop();
                    result = Integer.parseInt(n2) - Integer.parseInt(n1);
                    break;
                case "*":
                    n1 = stack.pop();
                    n2 = stack.pop();
                    result = Integer.parseInt(n2) * Integer.parseInt(n1);
                    break;
                case "/":
                    n1 = stack.pop();
                    n2 = stack.pop();
                    result = Integer.parseInt(n2) / Integer.parseInt(n1);
                    break;
                default:
                    break;
                }
                stack.push(result + "");
            }
            System.out.println("result:" + result);
        }
        return result;

    }

    // 将中缀表达式转化成后缀表达式
    public static String change(String string) {
        Stack<Character> stack = new Stack<Character>();
        char[] chars = string.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (char c : chars) {
            System.out.println(stack);
            System.out.println(sb.toString());
            // 判断是否是数字如果是数字追加到StringBuffer中
            if (c >= '0' && c <= '9') {
                sb.append(c);
            } else {
                // 数字和运算符
                if (!(sb.charAt(sb.length() - 1) == ' ')) {
                    sb.append(" ");
                }
                // 判断栈是否为空,当栈空时直接将当前的运算压进栈中
                if (stack.empty()) {
                    stack.push(c);
                    continue;
                }
                // 当当前字符')' 则栈顶元素依次输出,直到')'为止
                if (c == ')') {
                    while (stack.peek() != '(') {
                         System.out.println(stack.peek());
                        char cc = stack.pop();
                        sb.append(cc + " ");
                    }
                    stack.pop();
                    continue;
                }
                //如果当前运算符的优先级低于栈顶运算符的优先级那么弹出栈顶的运算符,并将当前的运算符压进栈中;直到栈顶元素为'('
                else if (map.get(c) <= map.get(stack.peek())&&stack.peek()!='(') {
                    while (!stack.isEmpty()
                            && map.get(c) <= map.get(stack.peek())) {
                         System.out.println(c);
                        char cc = stack.pop();

                        if (cc != '(') {
                            sb.append(cc + " ");
                        }else{
                            break; 
                        }
                    }
                    stack.push(c);
                }
//              如果当前运算符的优先级高于栈顶运算符的优先级那么直接压进栈中
                else {
                    stack.push(c);
                }
            }

        }
        //将栈中剩余的运算符追加到表达式尾部
        while (!stack.isEmpty()) {
            sb.append(" " + stack.pop());
        }

        return sb.toString();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值