AcWing 3302. 表达式求值——算法基础课题解

2024-05-16 09:44

本文主要是介绍AcWing 3302. 表达式求值——算法基础课题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AcWing 3302. 表达式求值

题目描述

给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

注意:

  • 数据保证给定的表达式合法。
  • 题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-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。

输入样例

(2+2)*(1+1)

输出样例

8

C++

#include <iostream>
#include <algorithm>
#include <stack>
#include <unordered_map>using namespace std;// 用于存储操作数的栈
stack<int> num;
// 用于存储操作符的栈
stack<char> op;// 执行一次计算操作
void eval() {// 获取并弹出栈顶的两个操作数auto b = num.top();num.pop();auto a = num.top();num.pop();// 获取并弹出栈顶的操作符auto c = op.top();op.pop();int x;// 根据操作符进行相应的计算if (c == '+') x = a + b;else if (c == '-') x = a - b;else if (c == '*') x = a * b;else x = a / b;// 将计算结果压回操作数栈num.push(x);
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);// 定义操作符优先级的映射unordered_map<char, int> pr{{'+', 1},{'-', 1},{'*', 2},{'/', 2}};string str;// 读取输入的表达式cin >> str;// 遍历输入的表达式for (int i = 0; i < str.size(); i++) {auto c = str[i];// 如果当前字符是数字if (isdigit(c)) {int x = 0, j = i;// 提取完整的数字while (j < str.size() && isdigit(str[j]))x = x * 10 + str[j++] - '0';// 更新索引ii = j - 1;// 将数字压入操作数栈num.push(x);}// 如果当前字符是左括号else if (c == '(') op.push(c);// 如果当前字符是右括号else if (c == ')') {// 处理所有括号内的操作符while (op.top() != '(') eval();// 弹出左括号op.pop();}// 如果当前字符是操作符else {// 处理优先级高于或等于当前操作符的操作符while (!op.empty() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();// 将当前操作符压入操作符栈op.push(c);}}// 处理栈中剩余的操作符while (!op.empty()) eval();// 输出最终结果cout << num.top() << endl;return 0;
}

Go

package mainimport ("container/list""fmt"
)// 用于存储操作数的栈
var num *list.List// 用于存储操作符的栈
var op *list.List// 执行一次计算操作
func eval() {// 获取并弹出栈顶的两个操作数b := num.Remove(num.Back()).(int)a := num.Remove(num.Back()).(int)// 获取并弹出栈顶的操作符c := op.Remove(op.Back()).(rune)var x int// 根据操作符进行相应的计算switch c {case '+':x = a + bcase '-':x = a - bcase '*':x = a * bcase '/':x = a / b}// 将计算结果压回操作数栈num.PushBack(x)
}func main() {// 定义操作符优先级的映射pr := map[rune]int{'+': 1,'-': 1,'*': 2,'/': 2}num = list.New()op = list.New()var str stringfmt.Scan(&str)// 遍历输入的表达式for i := 0; i < len(str); i++ {c := rune(str[i])// 如果当前字符是数字if '0' <= c && c <= '9' {x := 0j := i// 提取完整的数字for j < len(str) && '0' <= rune(str[j]) && rune(str[j]) <= '9' {digit := int(str[j] - '0')x = x*10 + digitj++}// 更新索引ii = j - 1// 将数字压入操作数栈num.PushBack(x)} else if c == '(' { // 如果当前字符是左括号op.PushBack(c)} else if c == ')' { // 如果当前字符是右括号// 处理所有括号内的操作符for op.Back().Value.(rune) != '(' {eval()}// 弹出左括号op.Remove(op.Back())} else { // 如果当前字符是操作符// 处理优先级高于或等于当前操作符的操作符for op.Len() > 0 && op.Back().Value.(rune) != '(' && pr[op.Back().Value.(rune)] >= pr[c] {eval()}// 将当前操作符压入操作符栈op.PushBack(c)}}// 处理栈中剩余的操作符for op.Len() > 0 {eval()}// 输出最终结果fmt.Println(num.Back().Value.(int))
}

这篇关于AcWing 3302. 表达式求值——算法基础课题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/994554

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO