算法刷题笔记 表达式求值(C++实现)

文章目录

    • 题目描述
    • 基本思路
    • 实现代码

题目描述

  • 给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。
  • 注意
    • 数据保证给定的表达式合法。
    • 题目保证符号-只作为减号出现,不会作为负号出现,例如,-1+2,(2+2)*(-(1+1)+2) 之类表达式均不会出现。
    • 题目保证表达式中所有数字均为正整数。
    • 题目保证表达式在中间计算过程以及结果中,均不超过2^31−1
    • 题目中的整除是指向0取整,也就是说对于大于0的结果向下取整,例如5/3=1,对于小于0的结果向上取整,例如5/(1−4)=−1。C++和Java中的整除默认是向零取整;Python中的整除//默认向下取整,因此Python的eval()函数中的整除也是向下取整,在本题中不能直接使用。

输入格式

  • 共一行,为给定表达式。

输出格式

  • 共一行,为表达式的结果。

数据范围

  • 表达式的长度不超过10^5

基本思路

  • 这道题是一道经典的算法模板题,即中缀算术表达式求值。这一类模板题中,所采用的运算符基本上都是二元运算符,需要借助的数据结构是栈,利用该数据结构先进后出的特性。
  • 首先,我们分析一下中缀表达式求值的难点是什么,可以发现该问题的难点在于一个算术表达式中,具有不同类型的运算符,有时候甚至带有括号,使得先进行什么运算,然后进行什么运算变得困难,因此该问题的核心就是确定表达式中各个运算的相对顺序。
  • 本题中之所以采用栈这种数据结构,是因为栈中元素的出栈顺序即可表示表达式中各个运算符之间的运算顺序;另外,用一个栈存储运算数,可以记录不同运算数之间参与运算的先后顺序。

实现代码

#include <iostream>       // 使用C++中的cin和cout进行输入输出更加简单
#include <cctype>         // 使用isdigit函数需要导入的头文件
#include <stack>          // 使用STL中自带的栈需要导入的头文件
#include <unordered_map>  // 使用STL中自带的哈希表(字典)需要导入的头文件
using namespace std;

stack<int> numbers;     // 运算优先级越高的数字,越靠近栈顶
stack<char> operators;  // 运算优先级越高的运算,越靠近栈顶
// 以哈希表(相当于Python中的字典)的形式记录不同运算符的优先级(如果有更多的运算符则修改此表即可)
unordered_map<char, int> priority{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};

void get_value(void)
{
    int number2 = numbers.top(); numbers.pop();
    int number1 = numbers.top(); numbers.pop();
    char operation = operators.top(); operators.pop();
    switch(operation)
    {
        case '+' : numbers.push(number1 + number2);break;
        case '-' : numbers.push(number1 - number2);break;
        case '*' : numbers.push(number1 * number2);break;
        case '/' : numbers.push(number1 / number2);break;
    }
}

int main(void)
{
    // 以C++字符串的形式输入中缀算术表达式
    string expression;
    cin >> expression;
    // 遍历整个字符串,确保表达式中的所有运算和数字都存入了栈
    for(int i = 0; i < expression.length(); ++ i)
    {
        // 情况1:读入的字符是数字(使用cctype头文件中的isdigit函数判定),则将其与运算符分开
        if(isdigit(expression[i]))
        {
            // 数字可能是多位整数,因此需要循环判定下一个字符是否也是数字
            int number = 0;
            // 使用条件表达式的短路规则进行判定,即表达式没有遍历完,且当前字符为数字
            while(i < expression.length() && isdigit(expression[i]))
            {
                // 记录当前的数字的值并自增位置
                number = number * 10 + (expression[i] - '0');
                ++ i;
            }
            // 将每一个运算数都压入运算数栈并更新位置
            numbers.push(number);
            -- i;
        }
        // 情况2:读入的字符是左括号,则直接将其入栈即可而无需判定
        else if(expression[i] == '(') operators.push('(');
        // 情况3:读入的字符是右括号,由于括号内优先级高,因此先计算括号内的
        else if(expression[i] == ')') 
        {
            // 持续进行运算,直到找到该右括号对应的左括号,并将左括号出栈
            while(operators.top() != '(') get_value();
            operators.pop();
        }
        // 情况4:读入的字符是二元运算符(加减乘除)
        else 
        {
            // 当运算符栈不为空,且当前遍历到的运算符的优先级不高于栈顶的元素的优先级,则先取出栈顶的元素进行计算
            while(!operators.empty() && priority[expression[i]] <= priority[operators.top()]) get_value();
            // 运算完成后将当前遍历到的运算符入栈
            operators.push(expression[i]);
        }
    }
    // 遍历完了表达式,运算过程可能仍然没有结束,需要继续运算直到运算符栈为空
    while(!operators.empty()) get_value();
    // 输出运算数栈的栈顶元素
    cout << numbers.top();
    return 0;
}
  • isdigit函数:用于判定一个字符是否是数字字符(0-9),使用时需要导入头文件<cctype>
  • 短路原则:在使用&&连接的表示“与”的条件表达式中,只有前一个条件表达式为真,才会继续判定下一个条件表达式,因此在代码情况1中的while语句,并不会出现expression[i]越界的问题。
  • 栈的操作:C++的STL中提供了栈模板类,使用时需要首先导入头文件<stack>。可以使用栈对象的top()函数获取栈顶元素,使用pop()函数弹出栈顶元素(无返回值),使用empty()函数判定栈是否为空(返回布尔值),使用push()函数入栈一个元素。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《UDS协议从入门到精通》系列——图解0x84:安全数据传输

《UDS协议从入门到精通》系列——图解0x84&#xff1a;安全数据传输 一、简介二、数据包格式2.1 服务请求格式2.2 服务响应格式2.2.1 肯定响应2.2.2 否定响应 Tip&#x1f4cc;&#xff1a;本文描述中但凡涉及到其他UDS服务的&#xff0c;均提供专栏内文章链接跳转方式以便快速…

Stable Diffusion最强功能—— 图片背景完美替换

今天分享 Stable Diffusion 图片背景完美替换 功能&#xff0c;通过 Stable Diffusion 图生图重绘蒙版进行背景图的二次重绘。 在广告产品图、头像背景替换、图片后期处理等场景下用到的都很频繁。 整体步骤&#xff1a; 通过 removebg 插件实现图片主体蒙版的抠图 结合图生…

提升研发效能的67个技术点丨IDCF

在当今快速变化的市场环境中&#xff0c;企业要想保持竞争力&#xff0c;就必须不断提高研发效率。高效的研发不仅能够帮助企业快速响应市场需求&#xff0c;还能降低成本、提高产品质量。本文让我们一起来看一下&#xff0c;作为微软18年MVP的技术大咖徐磊老师&#xff0c;梳理…

HTML CSS 基础复习笔记 - 列表使用

用于自己复习 自定义列表 示例代码 <!DOCTYPE html> <html> <head><title>Definition List Example</title> </head> <body><h1>古诗</h1><dl><dt>静夜思</dt><dd>床前明月光&#xff0c;疑…

使用dot来画流程图

Dot是一种图形描述语言&#xff0c;属于Graphviz软件的一部分。Graphviz是一个用于可视化图形&#xff08;图表、网络图等&#xff09;的开源工具集。使用Dot语言&#xff0c;你可以创建并描述节点和边&#xff0c;从而生成图形。以下是如何使用Dot语言画图的基本步骤&#xff…

修复 OpenSSH 爆出极其严重的安全漏洞!

最近几天OpenSSH爆出了一个高危漏洞&#xff1a;CVE-2024-6387&#xff0c;影响到了很多的Linux服务器系统。明月第一时间给所有的代维客户服务器进行了排查和漏洞修复&#xff0c;因此耽搁了一些时间。直到今天才算抽出空来给大家分享一下。严格上来说这个漏洞的危险性还是极高…

Beyond Compare 解锁版下载及安装教程 (文件和文件夹比较工具)

前言 Beyond Compare 是一款功能强大的文件和文件夹比较工具。它支持文件夹比较、文件夹合并与同步、文本比较、表格比较、图片比较、16进制比较、注册表比较、版本比较等多种功能。通过 Beyond Compare&#xff0c;您可以轻松调查文件和文件夹之间的不同之处&#xff0c;并使…

MySQL篇-SQL优化实战-减少子查询

回顾 上一篇了解了分析SQL使用的explain&#xff0c;可以点击查看MySQL篇-SQL优化实战了解我在写sql的注意事项还有explain的说明&#xff0c;这次拿一段生产使用的sql进行优化说明。从14s优化到2.6s 待优化的SQL SELECT DISTINCTswpe.tag_number,hca.ACCOUNT_NAME customer…

ELFK简介

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

K8S学习教程(二):在 PetaExpress KubeSphere容器平台部署高可用 Redis 集群

前言 Redis 是在开发过程中经常用到的缓存中间件&#xff0c;为了考虑在生产环境中稳定性和高可用&#xff0c;Redis通常采用集群模式的部署方式。 在制定Redis集群的部署策略时&#xff0c;常规部署在虚拟机上的方式配置繁琐并且需要手动重启节点&#xff0c;相较之下&#…

java基础:方法

一、方法 1、Java方法是语句的集合&#xff0c;它们在一起执行一个功能。 方法是解决一类问题的步骤的有序集合方法包含于类或对象中方法在程序中被创建&#xff0c;在其他地方被引用 2、设计方法的原则&#xff1a;方法的本意是功能块&#xff0c;就是实现某个功能的语句块…

layui+jsp项目中实现table单元格嵌入下拉选择框功能,下拉选择框可手动输入内容或选择默认值,修改后数据正常回显。

需求 table列表中的数据实现下拉框修改数据&#xff0c;当默认的下拉框不符合要求时&#xff0c;可手动输入内容保存。内容修改后表格显示修改后的值同时表格不刷新。 实现 layui框架下拉框组件只能选择存在的数据&#xff0c;不支持将输入的内容显示在input中的功能&#x…

什么牌子的无线领夹麦克风好,一篇了解哪种领夹麦性价比高

随着5G技术的广泛应用&#xff0c;短视频平台迎来了前所未有的发展机遇&#xff0c;几乎每个地方都有人在记录生活&#xff0c;分享故事。在这样的背景下&#xff0c;户外直播和视频创作的需求急剧增长&#xff0c;然而&#xff0c;户外的复杂声场仅靠普通手机的录音功能实在难…

计算机网络之局域网

目录 1.局域网的基本概念 2.LAN的特性 3.局域网特点 4.拓扑结构 5.传输媒体的选择 6.传输媒体 7.传输技术 8.传输技术距离问题 9.LAN的逻辑结构 10.局域网工作原理 上篇文章内容&#xff1a;OSI七层体系结构 1.局域网的基本概念 局域网 是将分散在有限地 理范围内&…

Robust Test-Time Adaptation in Dynamic Scenarios--论文阅读

论文笔记 资料 1.代码地址 https://github.com/BIT-DA/RoTTA 2.论文地址 https://arxiv.org/abs/2303.13899 3.数据集地址 coming soon 1论文摘要的翻译 测试时间自适应(TTA)旨在使预先7训练的模型适用于仅具有未标记测试数据流的测试分布。大多数以前的TTA方法已经在…

SQL Server特性

一、创建表 在sql server中使用create table来创建新表。 create table Customers( id int primary key identity(1,1), name varchar(5) ) 该表名为Customers其中包含了2个字段&#xff0c;分别为id&#xff08;主键&#xff09;以及name。 1、数据类型 整数类型&#xff…

NAT地址转换实验,实验超简单

实验拓扑 实验目的 将内网区域&#xff08;灰色区域&#xff09;的地址转换为172.16.1.0 实验过程 配置静态NAT&#xff08;基于接口的静态NAT&#xff09; R1配置 <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sysname R1 [R1]un in en I…

探索 Apache Paimon 在阿里智能引擎的应用场景

摘要&#xff1a;本文整理自Apache Yarn && Flink Contributor&#xff0c;阿里巴巴智能引擎事业部技术专家王伟骏&#xff08;鸿历&#xff09;老师在 5月16日 Streaming Lakehouse Meetup Online 上的分享。内容主要分为以下三个部分&#xff1a; 一、 阿里智能引擎…

流程表单设计器开源优势多 助力实现流程化!

实现流程化办公是很多职场企业的发展目标。应用什么样的软件可以实现这一目的&#xff1f;低代码技术平台、流程表单设计器开源的优势特点多&#xff0c;在推动企业降本增效、流程化办公的过程中作用明显&#xff0c;是理想的软件平台。那么&#xff0c;流程表单设计器开源的优…

VS开发QT程序图标修改

VS开发QT程序图标修改 1.双击打开UI界面 2.选择编辑资源 3.添加文件 4.选择ico文件 5.ok确定 6.点击保存 7.选择windowsIcon,倒三角图标 8.选择资源 9.选择图标&#xff0c;点击ok 10.保存 编译运行&#xff1a; 任务栏&#xff1a; 或者代码设置: 添加图标后&#xff0c;打…
最新文章