224. 基本计算器

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

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

 

示例 1:

输入:s = "1 + 1"
输出:2

示例 2:

输入:s = " 2-1 + 2 "
输出:3

示例 3:

输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23

 

提示:

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

 

  bool isOperator(char c)

{

    if (c == '+' || c == '-' || c == '*' || c == '/' || c == ' ' || c == '(' || c == ')')

        return true;

    return false;

}

int getNum(string &s, int start, int &end)

{

    int cur = start;

    bool isNegative = false;

    if (cur < s.size() && s[cur] == '-')

    {

        isNegative = true;

        cur++;

        start = cur;

    }

    while (cur<s.size() && isOperator(s[cur]) == false)

    {

        if (s[cur] == ' ')

        {

            cur++;

            continue;

        }

        cur++;

    }

    string tmp = s.substr(start, cur - start);

    end = cur;

    int a = std::stoi(tmp);

    if (isNegative)

    {

        a *= -1;

    }

    return a;

}

void calNum(stack<int>&numStk, stack<char> &symbolStk)

{

    char c = symbolStk.top();

    symbolStk.pop();

    int a = numStk.top();

    numStk.pop();

    int b = numStk.top();

    numStk.pop();

    switch (c)

    {

    case '+':

        numStk.push(a + b);

        break;

    case '-':

        numStk.push(b - a);

        break;

    case '*':

        numStk.push(a*b);

        break;

    case '/':

        numStk.push(b / a);

        break;

    default:

        break;

    }

}

bool isSameSymbol(stack<char> &symbolStk, char c)

{

    if (c == '-' || c == '+')

    {

        if (symbolStk.size() > 0 && (symbolStk.top() == '-' || symbolStk.top() == '+'))

        {

            return true;

        }

    }

    if (c == '/' || c == '*')

    {

        if (symbolStk.size() > 0 && (symbolStk.top() == '/' || symbolStk.top() == '*'))

        {

            return true;

        }

    }

    return false;

}

//#include <string>

//#include <algorithm>

#include <cctype>

int calculate(string s) {

    s.erase(std::remove_if(s.begin(), s.end(), [](char c) {return std::isspace(c);}), s.end());

    stack<int>numStk;

    stack<char> symbolStk;

    int cur = 0;

    while (cur<s.size())

    {

        bool isNum = false;

        if (s[cur] == ' ')

        {

            cur++;

            continue;

        }

        if (s[cur] == '-')

        {

            if (cur == 0 ||s[cur-1]=='(' ) //前面补充 0

            {

                numStk.push(0);

                symbolStk.push('-');

                cur++;

                continue;

            }

            else if (cur - 1 >= 0 && s[cur-1]!=')' && isOperator(s[cur - 1]))

            {

                numStk.push(getNum(s, cur, cur));

                isNum = true;

            }

            else

            {

                if (isSameSymbol(symbolStk, s[cur]))

                {

                    calNum(numStk, symbolStk);

                }

                symbolStk.push('-');

                cur++;

                continue;

            }

        }

        //符号

        else if (isOperator(s[cur]))

        {

            if (s[cur] == ')')

            {

                //计算

                while (symbolStk.top() != '(' && numStk.size()>=2)

                {

                    calNum(numStk, symbolStk);

                }

                symbolStk.pop();//'('

                cur++;

                continue;

            }

            else

            {

                if (isSameSymbol(symbolStk, s[cur]))

                {

                    calNum(numStk, symbolStk);

                }

                symbolStk.push(s[cur]);

                cur++;

                continue;

            }

        }

        //数字

        else

        {

            numStk.push(getNum(s, cur, cur));

            isNum = true;

        }

        //处理 * /

        if (isNum == true)

        {

            if (symbolStk.size()>0 && (symbolStk.top() == '*' || symbolStk.top() == '/'))

            {

                calNum(numStk, symbolStk);

            }

        }

    }

    if (symbolStk.size()>0 && numStk.size()>=2)

    {

        calNum(numStk, symbolStk);

    }

    //最后一个是负数

    if (symbolStk.size()>0 && symbolStk.top() == '-')

    {

        return numStk.top()* -1;

    }

    return numStk.top();

}

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

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

相关文章

CentOS 7遗忘了root密码怎么办?

正文共&#xff1a;666 字 12 图&#xff0c;预估阅读时间&#xff1a;1 分钟 说来也巧&#xff0c;突然发现使用KVM在部署CentOS时&#xff08;笔记本电脑安装CentOS系统&#xff09;&#xff0c;会有一个神奇的现象&#xff0c;还不是偶然出现的&#xff0c;在最近的三四次部…

4种叶轮平衡技巧 提高精度,降低故障率

在风机运作时&#xff0c;叶轮的动平衡是关键因素之一&#xff0c;不平衡的叶轮会产生振动和噪音&#xff0c;影响风机性能&#xff0c;甚至可能导致故障。 因此&#xff0c;掌握合适的平衡技术对提高设备稳定性和延长使用寿命至关重要。 本文将探讨几种有效的叶轮平衡方法及…

java中Request和Response的详细介绍

1.Request和Response的概述 # 重点 1. service方法的两个参数request和response是由tomcat创建的void service(ServletRequest var1, ServletResponse var2) 2. request 表示请求数据, tomcat将浏览器发送过来的请求数据解析并封装到request对象中servlet开发者可以通过reques…

力扣第224题“基本计算器”

在本篇文章中&#xff0c;我们将详细解读力扣第224题“基本计算器”。通过学习本篇文章&#xff0c;读者将掌握如何使用栈来解析和计算表达式&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述 力扣第224题“…

单向链表的数据存储(申请堆空间)

函数功能&#xff1a; 0.排序&#xff08;逆置和顺序排序&#xff09; 1.回显 2.头插 3.位插 4.尾插 5.尾删 6.头删 7.位删 8.查找 &#xff08;按值或按位查找&#xff09; 9.修改 &#xff08;按值或按位修改&#xff09; 10.退出 main.c …

Win11系统vscode配置C语言环境

安装Visual Studio Code&#xff1a; 如果你还没有安装VSCode&#xff0c;请从官方网站下载并安装&#xff1a;https://code.visualstudio.com/ 安装C/C扩展&#xff1a; 打开VSCode&#xff0c;进入扩展视图&#xff08;点击侧边栏的扩展图标或使用快捷键CtrlShiftX&#xff…

基于AWS Billing Conductor自定义账单计算进行【linker账单】RI/SP还原以及账单菜单栏选择性精细化限制策略设置

文章目录 一、客户需求需求① 设置策略屏蔽billing菜单选项查看需求② 账单RI和SP还原及SP和RI的共享 二、AWS Billing Conductor介绍三、IAM 精细操作映射参考四、详细步骤操作演示4.1 AWS Organization策略设置4.2 账单和成本管理设置4.3 AWS Billing Conductor设置4.3.1 创建…

allWebPlugin中间件实现ActiveX插件在谷歌、火狐、Edge浏览器使用

下载并安装allWebPlugin中间件 1、请从下面地址下载allWebPlugin中间件产品&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1xUyQDzOabh7mU7J7TYhtig?pwdz3q0 提取码&#xff1a;z3q0 如下图所示&#xff0c;下载最新allWebPlugin_x86_v2.0.0.14_stable_20240707…

Redis 管道技术

Redis 管道技术 引言 Redis&#xff0c;作为一个高性能的键值存储系统&#xff0c;被广泛应用于各种场景&#xff0c;如缓存、消息队列等。为了进一步提高Redis的处理能力和效率&#xff0c;Redis管道技术应运而生。本文将深入探讨Redis管道技术的原理、应用及其优势。 什么…

LiveNVR监控流媒体Onvif/RTSP用户手册-录像计划:批量配置、单个配置、录像保存(天)、配置时间段录像

TOC 1、录像计划 支持单个通道 或是 通道范围内配置支持快速滑选支持录像时间段配置 1.1、录像存储位置如何配置&#xff1f; 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 支持 Windows Linux 及其它CPU架构&#xff08;国产、嵌入式…&#xff09;操作系统安装包下载 、 安装…

【文件格式转换】Python转换 pdf 到 word (docx)

要使用 Python 将 PDF 转换为 Word 文档&#xff0c;可以使用库pdf2docx。操作方法如下&#xff1a; 安装必要的库&#xff1a; pip install pdf2docx使用以下 Python 代码将 PDF 文件转换为 Word 文档&#xff1a; from pdf2docx import Converterdef pdf_to_word(pdf_file…

调度pass的定制

概述 作为调度pass实现类&#xff0c;MachineScheduler 和 PostMachineScheduler 的优点之一是允许开发者在LLVM 已有调度算法和策略基础上做不同的定制化 PostMachineScheduler 类的定制相对简单&#xff0c;主要是MachineSchedStrategy 接口的定制。 MachineScheduler 类的…

【算法】Dijkstra算法

戴克斯特拉算法(Dijkstras Algorithm),由荷兰杰出计算机科学家艾兹赫尔戴克斯特拉设计,是解决非负权有向图中单源最短路径问题的经典算法。它构建了一个逐步扩展的最短路径树,从指定的源点出发,逐步探索并确定到图中所有其他顶点的最短路径。这一算法在网络路由选择、地理…

C语言旋转动画

目录 开头程序程序的流程图C语言旋转动画(程序的效果)结尾 开头 大家好&#xff0c;我叫这是我58。在这里&#xff0c;我们要来看我用C语言编译成的可以顺时针或者逆时针旋转的动画相关的一些东西和那个动画的顺时针与逆时针的版本。 程序 #define _CRT_SECURE_NO_WARNINGS …

Hospital Management System v4.0 SQL 注入漏洞(CVE-2022-24263)

前言 CVE-2022-24263 是一个影响 Hospital Management System (HMS) v4.0 的 SQL 注入漏洞。这个漏洞允许攻击者通过注入恶意 SQL 代码来获取数据库的敏感信息&#xff0c;甚至可能控制整个数据库。以下是对这个漏洞的详细介绍&#xff1a; 漏洞描述 在 Hospital Management…

【MindSpore学习打卡】应用实践-自然语言处理-深入理解LSTM+CRF在序列标注中的应用

在自然语言处理(NLP)领域&#xff0c;序列标注是一项重要的任务。其目标是为给定的输入序列中的每个Token分配一个标签。序列标注的应用范围广泛&#xff0c;包括分词、词性标注、命名实体识别(NER)等。在本文中&#xff0c;我们将探讨如何利用LSTM和CRF模型进行序列标注&#…

无人机之穿越机知识篇

一、定义和类型 穿越机&#xff0c;即FPV Drone或Racing Drone&#xff0c;是一种主要通过第一人称视角&#xff08;FPV&#xff09;进行操作的无人机。这种无人机通常配备有四个电机和相应的飞控系统&#xff0c;使其具有极高的飞行自由度和速度。穿越机主要分为竞速型和花飞…

electron在VSCode和IDEA及webStrom等编辑器控制台打印日志乱码

window10环境下设置 1.打开Windows设置 2.打开时间和语言&#xff0c;选择语言菜单、如何点击管理语言设置 3.打开之后选择管理&#xff0c;选择更改系统区域设置&#xff0c;把Beta版&#xff1a;使用Unicode UTF-8提供全球语言支持 勾上&#xff0c;点击确定&#xff0c;…

C# —— try catch

代码出现错误的两种情况 编译错误: 编译不通过&#xff0c;只要是编译不通过 铁定执行不了&#xff0c;例如出现语法错误(少符号、中英文错误 爆红); 运行时候的错误: 程序在运行的期间出现的逻辑错误&#xff0c;例如(数组越界了 格式转换错误等) 异常代码: 例如除数如…

甄选范文“论区块链技术及应用”,软考高级论文,系统架构设计师论文

论文真题 区块链作为一种分布式记账技术,目前已经被应用到了资产管理、物联网、医疗管理、政务监管等多个领域。从网络层面来讲,区块链是一个对等网络(Peer to Peer, P2P),网络中的节点地位对等,每个节点都保存完整的账本数据,系统的运行不依赖中心化节点,因此避免了中…