题解 | #计算器(一)-(正常做法)-(符号击穿)#

计算器(一)

http://www.nowcoder.com/practice/9b1fca7407954ba5a6f217e7c3537fed

描述

题目描述

首先给我们一个字符串,这个字符串里面含有+,,(,)+, -, (, ),然后运算的优先级跟我们正常算数的运算优先级一样,让我们求出最后的值

样例解释

"1+2"

这个我们直接计算就可以,得到33

所以最后的输出是

3

需要注意

这里我们会有括号嵌套的情况,这里我们需要特殊注意一下顺序

题解

解法一:栈

解题思路

其实我们的这个整个操作都是可以分成三部分

左边表达式-运算符-右边表达式

然后这里我们可以使用栈来保存我们的左边表达式和符号位,我们每次计算完之后都更新一下,然后在于右边表达式进行操作,然后如果遇到了括号的嵌套,我们可以一直进栈,直到遇到右括号,这样我们可以保证我们的栈顶的元素就是我们的括号里面的运算结果

也就式我们要维护这么几个变量

  1. 左边表达式的值
  2. 当前运算符
  3. 当前遇到的数字

总体过程可以如下图所示

20220111104357

代码实现

class Solution {
public:
    int calculate(string s) {
        stack<int> num;
        stack<char> sign;
//         分别用于存储符号位和数值位
        int tmp = 0, sig = 1, res = 0;
//         这个分别式我们上一个的值,每一次的符号,和我们最后的答案
        for (auto &it : s) {
//             遍历我们的字符串
            if (it >= '0' and it <= '9') tmp = tmp * 10 + (it - '0');
//             这个是为了避免我们有多位,我们的数字不只一位
            else if (it == '+' or it == '-') {
//                 如果是加减法,我们进行一个运算
                res += sig * tmp;
                tmp = 0;
                it == '+' ? sig = 1 : sig = -1;
//                 更改我们的临时元素
            } else if (it == '(') {
//                 如果是括号的话,一直入栈
                num.push(res);
                sign.push(sig);
                res = 0, sig = 1;
            } else if (it == ')') {
//                 不断计算我们的值,然后出栈
                res += sig * tmp;
                tmp = 0;
                res *= sign.top();
                sign.pop();
                res += num.top();
                num.pop();
            }
        }
        res += sig * tmp;
//         把最后一位也给算上
        return res;
    }
};

时空复杂度分析

时间复杂度: O(n)O(n)

理由如下:主要的时间就是遍历了我们这个字符串的长度

空间复杂度: O(n)O(n)

理由如下:我们开辟了一个栈用于存储我们的数据和符号

解法二:模拟

解题思路

我们上面的方法还是考虑了括号,这里我们可以想一种更为暴力的做法,直接用我们的正负号把我们的括号完全拆开,只要考虑每次的符号即可和变号即可

代码实现

class Solution {
public:
    int calculate(string s) {
        stack<int> sign;
        int res = 0, tmp = 0, sig = 1;
//         分别位最后的答案,临时数,符号
        sign.push(sig);
//         我们开辟的栈用于存储符号
        for (auto &it : s) {
            if (it >= '0' and it <= '9') tmp = tmp * 10 + (it - '0');
//             避免这个数是多位数
            else {
                res += tmp * sig, tmp = 0;
//                 计算结果
                switch (it) {
                    case '+':
                        sig = sign.top();
                        break;
                    case '-':
                        sig = -sign.top();
                        break;
                    case '(':
                        sign.push(sig);
                        break;
                    default:
                        sign.pop();
                        break;
                }
//                 让我们从这里开始的符号位进行改变
            }
        }
        res += sig * tmp;
//         把最后一个也算进去
        return res;
    }
};

时空复杂度分析

时间复杂度: O(n)O(n)

理由如下:主要的时间就是遍历了我们这个字符串的长度

空间复杂度: O(n)O(n)

理由如下:我们开辟了一个栈用于存储我们的符号

机试题目题解 文章被收录于专栏

主要是机试题目的题目讲解和做法

全部评论

相关推荐

12-08 07:42
门头沟学院 Java
27届末九,由于是女生,身边人几乎没有就业导向的,自学只能跟着网课,没人指导,很迷茫。下图是我目前的简历,不知道有需要修改的地方吗?求拷打。下面是目前的学习情况:目前算法过完了一遍力扣100和代码随想录,不过不是很熟,面经看了小林coding、JavaGuide,有一些没用过的技术看得不是很明白,掌握得不是很扎实。再加上常年跟黑马网课听思路,真正自己动手写代码的时间很少,这让我一直不敢投简历,总觉得内里空虚。项目没准备好面试相关的问题,简历上相应的考点不熟。如此种种。。。看到很多很多学长学姐大佬们的面经,愈发觉得面试可怕,自己没准备好,总担心自己是不是无望后端开发了。看到牛客很多同届以及更小一届的同学都找到实习了,很希望自己也能找到实习。而自己又好像摸不到后端学习的门路,只能不断赞叹黑马虎哥写的代码真优雅!微服务架构实在巧妙!消息队列、redis、sentinel、nacos、mybatisplus等等的引入都会让我赞叹这些工具的设计者的巧思,以及包括但不限于Java语言的优雅。然而只是停留在了解的程度,并不熟练。我是很希望能够继续深入探索这些知识的,只不过有一大部分时间都花在学校课程上了。我感觉我被困住了,我一方面必须保证我能够有个不错的学业分使我能有我几乎不想选择的读研退路(还有个原因是复习不全我会焦虑考试挂科,因此我会做好全面的准备,而这一步很费时间),一方面在B站学习各种网课,一方面得考虑提升自己并不扎实的算法基础,另一方面还得准备八股面经。这让我有点苦恼,我好像没那么多时间,因为绝大部分时间都花在了复习学校科目中了。我好像处处用时间,但收效甚微。想问问各位大佬是怎么平衡时间的呢?算法、项目和八股是怎么准备的呢?有什么高效的方法吗?谢谢您们花时间阅读我的稿件!
菜菜狗🐶:大胆投,我当时也是害怕面试,投多了发现根本约不到面🤡
投递哔哩哔哩等公司6个岗位
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务