前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基本计算器

基本计算器

作者头像
狼啸风云
发布2023-11-11 10:18:15
1940
发布2023-11-11 10:18:15
举报
文章被收录于专栏:计算机视觉理论及其实现

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()

示例 1:

代码语言:javascript
复制
输入:s = "1 + 1"
输出:2

示例 2:

代码语言:javascript
复制
输入:s = " 2-1 + 2 "
输出:3

示例 3:

代码语言:javascript
复制
输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23

提示:

  • 1 <= s.length <= 3 * 105
  • s 由数字、'+''-''('')'、和 ' ' 组成
  • s 表示一个有效的表达式
  • '+' 不能用作一元运算(例如, "+1" 和 "+(2 + 3)" 无效)
  • '-' 可以用作一元运算(即 "-1" 和 "-(2 + 3)" 是有效的)
  • 输入中不存在两个连续的操作符
  • 每个数字和运行的计算将适合于一个有符号的 32位 整数

中缀表达式进行正常的四则运算,即按优先级高低先算括号里的再算括号外,就需要将中缀字符串转为逆波兰表达式再求解。

但是这道题并不是四则运算,而是只有加减的二则运算。运算符的优先级只有两层:1.括号;2.加减;

因此我们可以把括号展开,这样整个表达式就只有加减运算,都是同级运算。

1 + (3 - 2) - (6 - (4 + 5)) = 1 + 3 - 2 - 6 + 4 + 5

括号展开

对于括号展开,我们要一步到位将所有嵌套的括号都展开而不是一级一级去展开的话,我们就要直到每一级括号相对于最外层的符号是怎样的。

我们知道,如果括号之前的符号为+,则括号内的运算符号不变;如果括号之前的符号为-,则括号内的运算符要改变。 当存在多个括号嵌套时,不仅要看括号前的符号,还要看上一级的括号符号是什么,才能确定这一级括号的符号。

而最外一层的运算,我们可以看成整体有个括号的,最外一层的符号为正。

因此我们可以使用一个栈结构来存储每一层的符号,初始将+1入栈,表示最顶层的符号。 统一加减为求和

在上一步我们通过栈记录每一层括号的符号,模拟括号的展开。 由于将已经将括号展开了,那么就可以直接根据加减符号进行运算了。而减法实际上就是加上一个负数,即我们是在对一堆数进行累加,这些数由两部分组成:符号和数值。

number = sign * value

sign = 1, -1

value > 0

由于栈结构存储了每一层符号了,我们可以通过访问栈顶元素获取当前层的符号,然后再根据加减运算符对符号进行改变。即加号保持当前层符号不变,减号取反。

代码语言:javascript
复制
class Solution {

public:

    int calculate(string s) {

        stack<int> st({1});  // 符号栈,存放每一层的符号,一个括号表示一层;最顶层的符号为+1;

        int sign = 1;   // 值为1或-1,表示当前数的符号

        int res = 0;    // 结果

        int number;

        int n = s.size();

        int i = 0;

        while(i < n){

            if(isdigit(s[i])){

                // 如果为数字,生成数值

                number = 0;

                while(i < n && isdigit(s[i])){

                    number = number * 10 + (s[i] - '0');

                    i++;

                }

                // 累加和,真实数字等于符号乘以数值

                res += sign * number;

            }else{

                if(s[i] == '+'){

                    sign = st.top();   // 加号,获取当前层的符号

                }else if(s[i] == '-'){    

                    sign = -st.top();  // 减号,获取当前层的相反符号

                }else if(s[i] == '('){    

                    st.push(sign);      // 左括号,进入新一层,将当前层符号入栈

                }else if(s[i] == ')'){

                    st.pop();   // 右括号,完成一层的运算,弹出这一层符号

                }

                i++;    // 索引右移

            }

        }

        return res;

    }

};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档