[Leetcode] 227.基本计算器

news2024/9/22 2:03:33

标题:[Leetcode] 227.基本计算器

个人主页:@水墨不写bug


(图片来源于网络)



//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//         佛祖保佑       永无BUG     永不修改                      //



目录

一、[Leetcode] 227.基本计算器(点击进入题目)

算法操作:

算法原理:

 总结:


正文开始: 

        计算器你一定用过, 但是我们用的计算器一般是及时输入输出型的,我们输入一个计算表达式,然后计算器输出一个值代表结果。但是如果这个表达式存储在字符串结构中,又该如何计算结果呢?这就是本篇Leetcode题目分享的题目背景。

一、[Leetcode] 227.基本计算器(点击进入题目)

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

整数除法仅保留整数部分。

你可以假设给定的表达式总是有效的。所有中间结果将在 [-2^31, 2^31 - 1] 的范围内。

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

示例 1:

输入:s = "3+2*2"
输出:7

示例 2:

输入:s = " 3/2 "
输出:1

示例 3:

输入:s = " 3+5 / 2 "
输出:5

提示:

  • 1 <= s.length <= 3 * 10^5
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 2^31 - 1] 内
  • 题目数据保证答案是一个 32-bit 整数

 这一类题目是属于表达式求值的问题,这一类问题的通用解决方法就是使用栈来模拟这个过程。

         具体来说,我们需要两个栈,一个存储数字,另一个存储运算符。但是本题比较特别,题目要求中说明:表达式串中不含括号,所以这就会引出本题的优化解法:用一个栈和一个变量解决本题。

         那么如何解决这个问题呢?具体操作如下:

        首先我们需要给栈中的第一个数字添加一个符号‘+’。原因:当首个数据是正数时,添加‘+’不并影响计算,当首个数据是负数时,那么首个字符就会是‘-’,这样一来‘+’就需要更新为‘-’,同样不影响计算。而这样做的好处就是可以把对数据的处理统一起来,简化代码的逻辑。

        接下来,需要一种思想:对于一个数据,比如:+9,-8等;他们是由符号和数字组成的。我们需要对每一个数据的符号和数字分别处理:

        由于我们首先读取的是符号,所以需要将符号“存储起来”,等我们读取到这个符号的数字之后再对这个数据进行处理:

算法操作:

        如果我们读取的符号是‘+’,我们需要将这个数据直接压栈;

        如果我们读取的是‘-’,不同了,我们需要把这个数据的相反数压栈;

        如果我们读取‘*’;需要将这个数与栈顶top相乘,pop原来的top,最后把这个数据压栈,作为新的top;

        如果我们读取‘/’;需要:top/=数据,pop原来的top,把结果压入栈,作为新的top。

算法原理:

        这一串字符串没有(),这就表示同优先级的运算符是按照结合性运算的。

        ‘+’,‘-’,‘*’,‘/’的结合性都是从左到右,与自然数学相同。

        ‘*’,‘/’的优先级高于‘+’,‘-’,这就表明需要先计算他们。

        先计算‘+’,‘-’体现在:我们遇到‘+’,‘-’时,是直接与前一个数进行计算了。我们遇到的‘+’,‘-’一定是最左侧最先出现的‘+’,‘-’,是整个表达式中最先计算的部分,这就是我们的计算原理。

 (比如下面的这一段表达式:

        最先计算的是6*4,当我们读取到第一个‘*’时,6以及之前的数据已经压入栈中:

        就下来读取到‘4’,按照算法,将栈顶的top*=4,再压入栈中,这就完成了第一个乘法操作:

        对于除法操作,类似的,此时的栈顶数据top是乘法运算之后新压入的24,栈顶top/=2,结果是12,将12压入栈即可)

 

        最终,遍历完字符串之后,将栈中的所有数据求和即可:

 

         最终结果sum = 4 -3 +12 -123 +34。


 总结:

1.遇到操作符:

        更新记录符号(char类型)op;

2.遇到数字:

        (1)先把数字提取出来,存储在整形变量tem中;

        (2)分情况讨论,根据op的符号:

                        i,op == ‘+’,tem直接入栈;

                        ii,op == ‘-’,-tem入栈;

                        iii,op == ‘*’,直接乘到栈顶元素上;

                        iv,op == ‘/’,直接除到栈顶元素上。

参考代码:

class Solution {
public:
    int calculate(string s) {
        int n = s.size();
        int i = 0;
        char op = '+';

        vector<int> st;
        while(i < n)
        {
            if(s[i] == ' ') ++i;
            else if(s[i] >= '0' && s[i] <= '9')
                //提取出数字
            {
                int tem = 0;
                while(i < n && s[i] >= '0' && s[i] <= '9')
                {
                    tem = tem * 10 + (s[i++] - '0');
                }
                if(op == '+')
                {
                    st.push_back(tem);
                }
                else if(op == '-')
                {
                    st.push_back(-tem);
                }
                else if(op == '*')
                {
                    st.back()*=tem;
                }
                else 
                {
                    st.back()/=tem;
                }
            }
            else
            {
                op = s[i];
                i++;   
            }
        }
        int sum = 0;
        while(!st.empty())
        {
            sum += st.back();
            st.pop_back();
        }
        return sum;
    }
};

完~

未经作者同意禁止转载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2153874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux 获取指定端口的PID netsat awk

使用netstat -ntpl 获取指定端口的PID #获取端口19000对应的PID netstat -ntpl | grep 19000 | awk {print $NF} | awk -F/ {print $1}

vcs/verdi常用命令(持续更新)

1. 操作rtl 1.1 加载rtl命令 verdi -dbdir simv.daidir的目录 1.2 显示某时刻rtl的值 首先鼠标左键在波形上选中某个特定时刻&#xff0c;然后鼠标选中rtl代码文件&#xff0c;按x就会显示&#xff0c;再按x就会退出显示。 1.3 查找字符串 按/ 1.4 vcs将rtl的信号加载到…

mockito+junit搞定单元测试(2h)

一&#xff0c;简介 1.1 单元测试的特点 配合断言使用(杜绝 System.out )可重复执行不依赖环境不会对数据产生影响spring 的上下文环境不是必须的一般都需要配合 mock 类框架来实现 1.2 mock 类框架使用场景 要进行测试的方法存在外部依赖(如 db, redis, 第三方接口调用等)…

HashMap扩容时机是插入前还是插入后?

结论 不管是HashMap还是ConcurrentHashMap都是插入后。 过程为&#xff1a; 先计算哈希值。对应的哈希槽插入数据&#xff0c;决定是红黑树还是链表插入完毕才计算是否需要扩容&#xff0c;假如需要则扩容 源码 源码如下&#xff1a; 其中addCount方法里面写入扩容。

如何设置 Django 错误邮件通知 ?

Django 是一个强大的 web 框架&#xff0c;非常适合那些想要完美快速完成任务的人。它有许多内置的工具和特性&#xff0c;一个有用的特性是 Django 可以在出现错误时发送电子邮件提醒。这对开发人员和管理员非常有用&#xff0c;因为如果出现问题&#xff0c;他们会立即得到通…

STM32F407单片机编程入门(十二) FreeRTOS实时操作系统详解及实战含源码

文章目录 一.概要二.什么是实时操作系统三.FreeRTOS的特性四.FreeRTOS的任务详解1.任务函数定义2.任务的创建3.任务的调度原理 五.CubeMX配置一个FreeRTOS例程1.硬件准备2.创建工程3.调试FreeRTOS任务调度 六.CubeMX工程源代码下载七.小结 一.概要 FreeRTOS是一个迷你的实时操…

智慧校园建设解决方案建设系统简介

一、建设背景 1.1 政策背景 1.2 班牌的演变 1.3 建设愿景 二、 智慧班牌简介 三、智慧班牌系统 3.1 系统概述 3.2 软件平台功能交互简介 3.2.1 智慧班牌与管理平台间的功能关联 3.2.2 手机客户端&#xff08;管理员、教师、家长端&#xff09; 3.2.3 手机客户端&#x…

数据采集与预处理,前后端结合案例(有代码),Python连接MySQL,对MySQL的增删改查

Python对MySQL的增删改查 通过Python连接MySQL """连接MySQL数据库&#xff0c;并进行增删改查&#xff0c;同时查询了MySQL版本号&#xff0c;并做了动态注册的账号&#xff0c;实现过程&#xff1a;先向userinfo当中添加account、password新字段&#xff0c…

数据结构:内部排序

文章目录 1. 前言1.1 什么是排序&#xff1f;1.2 排序的稳定性1.3 排序的分类和比较 2. 常见的排序算法3. 实现常见的排序算法3.1 直接插入排序3.2 希尔排序3.3 直接选择排序3.4 堆排序3.5 冒泡排序3.6 快速排序3.6.1 hoare思想3.6.2 挖坑法3.6.3 lomuto前后指针法3.6.4 非递归…

软考(中级-软件设计师)计算机系统篇(0921)

I 计算机系统知识 一、考纲要求 数值及其转换 二进制、十进制和十六进制等常用数制及其相互转换 计算机内数据的表示 数值的表示&#xff08;原码、反码、补码、移码表示&#xff0c;整数和实数的机内表示&#xff0c;精度和溢出&#xff09;非数值表示&#xff08;字符和汉字…

AI直播新浪潮:无人视频自动直播,出圈再造辉煌,创业者首选!

AI直播新浪潮:无人视频自动直播&#xff0c;出圈再造辉煌&#xff0c;创业者首选&#xff01; 在数字化浪潮的汹涌澎湃中&#xff0c;AI技术正以前所未有的速度重塑着各行各业的边界&#xff0c;而直播行业作为数字内容消费的前沿阵地&#xff0c;正迎来一场由AI驱动的深刻变革…

MQ(RabbitMQ)笔记

初识MQ 同步调用优缺点 异步调用优缺点 总结&#xff1a; 时效性要求高&#xff0c;需要立刻得到结果进行处理--->同步调用 对调用结果不关心&#xff0c;对性能要求高&#xff0c;响应时间短--->异步调用

2024年华为杯-研赛F题论文问题一二讲解+代码分享

X射线脉冲星光子到达时间建模 摘要 脉冲星是一类高速自转的中子星&#xff0c;其自转形成规律性脉冲信号&#xff0c;类似于“宇宙中的灯塔”&#xff0c;因此被认为是极为精确的时钟。X射线脉冲星导航利用脉冲星信号为航天器提供时间和空间参考。通过比较脉冲信号到达航天器…

查找算法 01分块查找

自己设计一个分块查找的例子&#xff0c;不少于15个数据元素&#xff0c;并建立分块查找的索引 基于上述例子&#xff0c;计算查找成功的ASL、查找失败的ASL 拓展&#xff1a; ‌‌分块查找的平均查找长度&#xff08;‌ASL&#xff09;的计算公式如下‌&#xff1a;‌ ‌顺序…

Camunda流程引擎并发性能优化

文章目录 Camunda流程引擎一、JobExecutor1、工作流程2、主要作用 二、性能问题1、实际场景&#xff1a;2、性能问题描述3、总结 三、优化方案方案一&#xff1a;修改 Camunda JobExecutor 源码以实现租户 ID 隔离方案二&#xff1a;使用 max-jobs-per-acquisition 参数控制上锁…

ThreadLocal与AsyncLocal

简介 ThreadLocal 用于在多线程环境中创建线程局部变量&#xff0c;可以让每个线程独立地访问自己的变量副本&#xff0c;互不影响。 而 AsyncLocal 是 ThreadLocal 的异步版本&#xff0c;专门用于异步编程场景&#xff0c;在异步操作中它可以正确处理上下文切换。 ThreadLo…

ftp服务的管理及安全优化

1.ftp介绍 ftp : file transfer proto 互联中最老牌的文件传输协议 2.vsftpd安装及启用 环境 #server 主机 &#xff1a; # R3 # 192.168.10.130 # selinux 关闭 # 火墙开启 # dnf 安装设定完成 # #client 主机 &#xff1a; # R4 # 192.168.10.131 # selinux 关闭 …

C++之职工管理系统(细节Q)

指针初始化类 && 普通变量初始化类 抽象基类worker&#xff0c;只需编写 .h &#xff0c;无需 .cpp 底层实现 类 记得声明权限public&#xff01;&#xff01;&#xff01;不然默认private&#xff0c;主函数访问不了 记得继承父类 Worker * worker&#xff1a;指向Wo…

source insight学习笔记

目录 目的 基础配置 1、护眼的保护色 2、行号显示 基础操作 目的 记录一下使用source insight中遇到的问题。比如常见好用的基础配置&#xff0c;常用的基础操作等。主要是为了自己以后忘记了好找。自己写的东西总归看起来更舒服。 PS&#xff1a;目前是第一个版本&#…

Linux相关概念和重要知识点(5)(权限的修改、时间属性)

1.权限的修改 &#xff08;1&#xff09;提权行为 普通用户是会受到权限的限制&#xff0c;但root账户无视一切权限限制&#xff0c;因此当我们要获取更高的权限&#xff0c;有一种办法就是将自己变成root或者短暂拥有和root一样的权力。 普通用户 -> root &#xff1a;s…