牛客网 AB6 表达式求值

这一题是栈的应用,思路就是使用双栈的去记录数据。

栈1:记录数字。

栈2:记录操作符。

思路就是一次遍历,遍历的同事枚举每一个字符。需要一个hash表记录字符的优先级。

可能出现4种情况:

1.括号 "(" , 直接入栈,然后遍历下一个数。

2.括号 “)”, 需要把栈里面的数拿出来,进行计算,一直到匹配到一个字符为“(”为止。

3.如果是一个数字,需要考虑这个数字是不是一个多位数字,就是比如 1, 11, 111这种数                    字,因 为遍历的是字符,所以需要把它加起来。

4,。就是剩余的情况了,就是操作字符,直接计算就行了。

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

/**
 * @author xnl
 * @Description:
 * @date: 2022/5/23   21:06
 */
public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
//        String str = "1+2";
       String str = "(2*(3-4))*5";
        //String str = "3+2*3*4-1";
        System.out.println(solution.solve(str));
    }

    // 存储字符优先级
    Map<Character, Integer> charTable = new HashMap<Character, Integer>(3){{
        put('+', 1);
        put('-', 1);
        put('*', 2);
    }};

    public int solve (String s) {
        s = s.replaceAll(" ", ""); // 去掉多余的空格
        char[] chars = s.toCharArray();
        Stack<Integer> numStack = new Stack<>(); // 数字栈
        numStack.push(0); // 避免第一个数是负数的情况
        Stack<Character> characterStack = new Stack<>();// 字符栈
        for (int i = 0; i < chars.length; ){
            // 如果当前字符是括号
            if (chars[i] == '('){
                characterStack.push(chars[i++]);
                continue;
            }

            // 如果是结尾括号
            if (chars[i] == ')'){
                while (!characterStack.isEmpty() && characterStack.peek() != '(' ){
                    calculation(numStack, characterStack);
                }
                characterStack.pop();
                i++;
                continue;
            }

            // 如果是0-9的数字,可能是二位数或者三位数以此类推
            if (chars[i] >= '0' && chars[i] <= '9'){
                int temp = 0;
                while (i < chars.length && chars[i] >= '0' && chars[i] <= '9'){
                    temp = temp * 10 + (chars[i++] - '0');
                }
                numStack.push(temp);
            } else {
                if (!characterStack.isEmpty() && (chars[i] == '+' || chars[i] == '-' || chars[i] == '*')){
                    // 每次判断上一个字符和当前字符的优先级,优先级低或者相等的才可以被执行
                    if (characterStack.peek() != '(' &&charTable.get(chars[i]) <= charTable.get(characterStack.peek())) {
                        calculation(numStack, characterStack);
                    }
                }
                characterStack.push(chars[i++]);
            }
        }
        // 把多余栈的数据给他清一下
        while (!characterStack.isEmpty()){
            calculation(numStack, characterStack);
        }
        return numStack.peek();
    }

    /**
     * 计算栈内数据的方法,,是一个计算器
     * @param nums
     * @param characters
     */
    private void calculation(Stack<Integer> nums, Stack<Character> characters) {
        if (nums.isEmpty() || characters.isEmpty()) {
            return;
        }

        Integer num1 = nums.pop();
        Integer num2 = nums.pop();
        Character c = characters.pop();

        if (c == '+') {
            nums.push(num1 + num2);
        } else if (c == '-') {
            nums.push(num2 - num1);
        } else if (c == '*') {
            nums.push(num1 * num2);
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值