Leetcode高级挑战:简单计算器

《简单计算器》在Leetcode中难度为hard,看起来很简单,里面涉及很多状态记录和汇总,真正做出来还是花了一些时间

1,问题

原题链接 https://leetcode.com/problems/basic-calculator/description/

  • 实现一个计算器来计算一个简单表达式。表达式中可以包含,左括号,右括号,加号,减号,数字或者空格
例1
Input: "1 + 1"
Output: 2
例2
Input: "(1+(4+5+2)-3)+(6+8)"
Output: 23
例3
Input: "(3-(2-(5-(9-(4)))))"
Output: 1

2,分析

  1. 看到问题我首先想到递归,依次深入,最后从最小的计算单位算起。思路没问题,但效率肯定不高。
  2. 如果要效率最高,最好的算法一定是只经过一次遍历就可以得出结果,所以我开始从这个思路下手。
  3. 这个问题可以分解为对每个数字进行加减法,没有括号的情况很简单。
  4. 有括号的情况,特别是嵌套的时候,括号里的数字应该做加法还是减法,需要考虑之前的操作符号。
  5. 比如例3中 "(3-(2-(5-(9-(4)))))", 数字5, 因为前面2个括号前都是负号,所以对数字5应该做加法

3,算法

  • 初始化,默认最近的计算符为加号

  • 遍历表达式中的字符

    • 如果字符为数字,获取整个数字串转化为数字
      • 根据最近的计算符累加
    • 如果字符为:左括号
      • 括号前的操作符入栈
      • 计算出栈中所有操作符累计结果
      • 设置最近的计算符为加号
    • 如果字符为:加号
      • 设置最近的计算符为加号
    • 如果字符为:减号
      • 设置最近的计算符为负号
    • 如果字符为:右括号
      • 设置最近的计算符为加号
      • 括号前的操作符出栈
  • 返回最终结果

4,完整代码

public int calculate(String s) {
        // 以下使用boolean类型来表示加加法,true为加法,false为减法
        boolean operArr[] = new boolean[s.length()];
        boolean finalOperInArr = true;
        int operOff = 0;

        int ret = 0;
        boolean lastOperPlus = true;

        for(int i=0; i<s.length(); i ++){
            if (Character.isDigit(s.charAt(i))) {
                // 获得整个数字
                int sum = s.charAt(i) - '0';
                while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
                    sum = sum * 10 + s.charAt(i + 1) - '0';
                    i++;
                }

                // 根据最近的操作符累加
                if(lastOperPlus == finalOperInArr)
                    ret += sum;
                else
                    ret -= sum;
            }

            if(s.charAt(i)=='('){
                // 操作符入栈
                operArr[operOff++] = lastOperPlus;
                finalOperInArr = finalOperInArr == lastOperPlus;
                lastOperPlus = true;
            }else if(s.charAt(i) == '+'){
                lastOperPlus = true;
            }else if(s.charAt(i) == '-') {
                lastOperPlus = false;
            }else if(s.charAt(i)==')'){
                lastOperPlus = true;
                // 操作符出栈
                finalOperInArr = finalOperInArr == operArr[--operOff];
            }
        }

        return ret;
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,201评论 0 13
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,465评论 0 5
  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 19,066评论 17 410
  • lmain函数中执行了一个UIApplicationMain这个函数llintUIApplicationMain(...
    Mr_董阅读 168评论 0 0
  • 这是我在简书的009篇记录 1盘点自己做过什么,最近对什么比较关注 不设置条数 2罗列自己的兴趣 5个 兴趣的定义...
    范范范范同学阅读 929评论 0 1