前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >表达式求值

表达式求值

作者头像
用户7447819
发布2021-07-23 15:01:36
3290
发布2021-07-23 15:01:36
举报
文章被收录于专栏:面试指北面试指北面试指北

表达式求值

1. 题目描述

请写一个整数计算器,支持加减乘三种运算和括号。示例1

输入 "1+2" 返回值 3

输入 "(2*(3-4))*5" 返回值 -10

2. 题解

本题主要考察对于数据结构栈的使用。我们可以定义两个栈,操作数栈和操作符号栈,依次扫描输入,处理结果。

  • 定义操作数栈 numStack
  • 定义操作符号栈 opStack
  • opStack 增加特殊操作符号'#',表示为最后一个元素。
  • 输入字符串末尾同样加上'#'
  • 遍历输入,将数字入到numStack
    • 若该数字为第一个则直接入栈
    • 若该数字不为第一个且上一个输入字符为数字,考虑将栈顶数字乘10 再加上当前数字,入到操作数栈
  • 处理操作符号
    • 入栈opStack
    • numStack 吐出两个操作数
    • opStack 吐出操作符
    • 对值进行计算,并入到numStack
    • 吐出左括号
    • 左括号入栈 opStack
    • 处理负数操作符的情况,numStack 入0,opStack 入 '-'
    • 处理正数操作符的情况
    • 处理 '#' 符号,表示已经到达输入表达式的末尾,要进行计算
    • 将当前符号入到opStack
    • numStack 吐出两个操作数
    • opStack 吐出操作符
    • 对值进行计算,并入到numStack
    • 处理 '+' '-' '#' 符号
    • 处理左括号
    • 处理右括号,右括号表示已经需要进行计算,循环处理,执行条件是opStack栈顶不为左括号
    • 处理 '*'
  • 完成运算,返回numStack栈顶元素即为结果。

3. 参考代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    public int solve (String s) {
        // write code here
        Stack<Integer> numStack = new Stack<>();
        
        Stack<Character> opStack = new Stack<>();
        
        opStack.push('#');
        
        s += '#';
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            
            // 处理数字
            if(c >='0' && c <= '9') {
                // 第一个数字直接入栈
                if (i == 0) {
                    int num = c - '0';
                    numStack.push(num);
                    continue;
                } else {
                    char pre = s.charAt(i-1);
                    // 对数字进行进位处理
                    if (pre >= '0' && pre <= '9') {
                        int num = numStack.pop() * 10 + (c - '0');
                        numStack.push(num);
                    } else {
                        int num = c - '0';
                        numStack.push(num);
                    }
                    continue;
                }
            } else {
              // 处理加减符号运算符号
                if (c == '-' || c == '+' || c == '#') {
                    // 处理负数
                    if (c == '-' && (i == 0 || s.charAt(i - 1) == '(')) {
                        numStack.push(0);
                        opStack.push('-');
                        continue;
                    }
                    // 处理单独加符号
                    if (c == '+' && (i == 0 || s.charAt(i - 1) == '(')) {
                        continue;
                    }
                    
                    // 对运算符进行运算
                    while (opStack.peek() == '*' || opStack.peek() == '+' || opStack.peek() == '-'){
                        int b = numStack.pop();
                        int a = numStack.pop();
                        char op = opStack.pop();
                        switch (op){
                            case '*':
                                numStack.push(b * a);
                                break;
                            case '+':
                                numStack.push(a + b);
                                break;
                            case '-':
                                numStack.push(a - b);
                                break;
                        }
                    }
                    opStack.push(c);
                }
                if (c == '(') {
                    opStack.push(c);
                }
                // 当前是右括号,对结果进行计算
                if (c == ')') {
                    while (opStack.peek() != '('){
                        int b = numStack.pop();
                        int a = numStack.pop();
                        char op = opStack.pop();
                        switch (op){
                            case '*':
                                numStack.push(b * a);
                                break;
                            case '+':
                                numStack.push(a + b);
                                break;
                            case '-':
                                numStack.push(a - b);
                                break;
                        }
                    }
                    // 吐出左括号
                    opStack.pop();
                }
                if (c == '*') {
                    opStack.push(c);
                }
            }
        }
        return numStack.peek();
    }
}

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面试指北 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 表达式求值
    • 1. 题目描述
      • 2. 题解
        • 3. 参考代码
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档