没有括号的字符串四则运算
目录
- 问题
- 分析与解答
- eval
- sympy
- 消去法
- 逆波兰表达式
- 拓展思考
- 参考资料
问题
用代码实现一个method,这个method的入参是一个字符串,这个字符串是一个四则运算的算式,比如“1+2*3+4/2-3”;返回值是这个算式的运算结果,比如“1+2*3+4/2-3”的返回值是6,为了简化这个题目,这个入参的算式只包含加减乘除,不包含括号
分析与解答
四则运算是数学常见的运算法则,有现成的函数或者第三方库来解决,也可以自己写一个method。下面分别介绍几种方法,按照由易到难的顺序
eval
由于入参的算式只包含加减乘除,不包含括号,所以可以采用eval直接算,但是eval会存在注入风险。
# -*- encoding: utf-8 -*-
'''
@Project : Arithemitc
@Desc : 字符串转四则运算
@Time : 2024/05/25 09:28:12
@Author : 帅帅de三叔,zengbowengood@163.com
'''
import re
import operatordef arithmetic(expression):"""eval直接算"""return eval(expression)if __name__=="__main__":input = "1+2-3/2*2" #例子1+2-3/2*2, 1+2*3+4/2-3result = arithmetic(input)print(result)
sympy
sympy 是专用的数学符号计算库,在处理方程时候非常强大,但是运行效率稍微慢了点
import re
import operator
from sympy import sympify, simplifydef Arithemtic(origin_str): """去除优先级乘法和除法运算"""expr = str(origin_str) #转字符串result = simplify(sympify(expr))return resultif __name__=="__main__":input = "1+2-3/2*2" #1+2-3/2*2result = Arithemtic(input)print(result)
消去法
倘若优先级运算“x”和“/”不相邻,此时,可以先对“x"和”/“先单独计算把“x"和”/“前后两个数字先计算和合二为一,处理完就只有”+“和”-“两种运算了,下面这个可以实现“x”和“/”不相邻的情形,“x”和“/”相邻的情况还没想好。
# -*- encoding: utf-8 -*-
'''
@Project : Arithemitc
@Desc : 字符串转四则运算
@Time : 2024/05/25 09:28:12
@Author : 帅帅de三叔,zengbowengood@163.com
'''
import re
import operatordef Arithemtic(origin_str): """去除优先级乘法和除法运算"""expr = str(origin_str) #转字符串digits = re.findall(r'\d+', expr) #提取数字串digits = [eval(i) for i in digits] #转数字operations = re.findall(r'[+\-*/]', expr) #提取运算符号print(digits, operations)operators = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.truediv} #四则运算映射for i in range(len(operations)): #对运算列表循环try:if operations[i] == "*" or operations[i] =="/": #如果有乘法,除法,先算去除print(i, operations[i], digits[i], digits[i+1])digits[i] = operators[operations[i]](digits[i], digits[i+1]) #合并运算print(digits, operations)digits.pop(i+1) #剔除第i+1位数字operations.pop(i) #剔除第i位算符 except:continueprint(digits, operations) #此时只有加减运算for j in range(len(operations)): # print(digits[j]) digits[j+1] = operators[operations[j]](digits[j], digits[j + 1]) #咬合向前逐步运算result = digits[-1]print(result)return resultif __name__=="__main__":input = "1+2*3+4/2-3" #1+2-3/2*2result = Arithemtic(input)
逆波兰表达式
查阅资料说逆波兰表达式法可以用于解决没有括号的字符串四则运算,计算步骤如下:
1,字符串四则运算表达式转换为后缀表达式
2,从左到右遍历表达式中的每个元素;
3,如果当前元素是数字,将其压入栈中;
4,如果当前元素是运算符,则取出栈顶的两个数字进行计算,并将结果压入栈中;
5,当遍历完整个表达式后,栈顶就是最终结果。
import redef infix_to_postfix(expression): # 运算符优先级字典,越低越优先 precedence = {'+': 1, '-': 1, '*': 2, '/': 2} output = [] op_stack = [] # 辅助函数,用于检查是否为运算符 def is_operator(token): return token in '+-*/' # 分割表达式为tokens tokens = re.findall(r'[+\-*/]|\d+', expression) for token in tokens: if token.isdigit(): # 如果是数字,直接输出 output.append(token) elif is_operator(token): # 如果是运算符 # 弹出并输出所有优先级更高或等于当前运算符的运算符 while op_stack and is_operator(op_stack[-1]) and \precedence[op_stack[-1]] >= precedence[token]: output.append(op_stack.pop()) # 将当前运算符压入栈 op_stack.append(token) else: # 如果是非法字符,抛出异常 raise ValueError(f'Invalid token: {token}') # 弹出并输出所有剩余的运算符 while op_stack: output.append(op_stack.pop()) return ' '.join(output) def evaluate_postfix(postfix_expr): stack = [] for token in postfix_expr.split(): # 假设表达式是空格分隔的字符串 if token.isdigit(): # 如果是数字 stack.append(int(token)) else: # 如果是运算符 operand2 = stack.pop() operand1 = stack.pop() if token == '+': result = operand1 + operand2 elif token == '-': result = operand1 - operand2 elif token == '*': result = operand1 * operand2 elif token == '/': # 注意:这里没有处理除数为0的情况 result = operand1 / operand2 else: raise ValueError(f"Invalid operator: {token}") stack.append(result) return stack.pop() # 返回最终结果 # 示例
infix_expr = "1+2-3/2*2"
postfix_expr = infix_to_postfix(infix_expr)
result = evaluate_postfix(postfix_expr)
print(f"Postfix expression: {postfix_expr}")
print(f"result: {result}")
拓展思考
1,根据乘法与除法的关系,除以某个数等于乘以这个数的倒数,可以将所有除法运算改成乘法运算,这种改变只会改变运算符号的右侧不会动左侧的;
2,根据乘法是加法的简便运算将所有乘法改成加法运算,这里存在一个非整数倍的问题需要用数值解法;
3,最后化成只有加法和减法的表达式,因为是对字符串操作,其中需要用到大量的正则运算和定位索引。
参考资料
1,逆波兰表达式介绍及求值实现
https://blog.csdn.net/wenwenaier/article/details/121236053
相关文章:
没有括号的字符串四则运算
目录 问题分析与解答evalsympy消去法逆波兰表达式拓展思考参考资料 问题 用代码实现一个method,这个method的入参是一个字符串,这个字符串是一个四则运算的算式,比如“12*34/2-3”;返回值是这个算式的运算结果,比如“…...
vue2 $set 后期添加响应式数据的问题,使用vm.$set()
文章目录 后期添加数据的问题后期给Vue的实例添加的属性,会有响应式吗?避免在运行时向vm或其根$data添加响应式 对象的响应式处理想给后期追加的属性添加响应式处理的,有以下俩个方法: 数组的响应式处理解决方案一:解决…...
笔记-X86下用Docker运行ARM64编译Libreoffice
初衷 针对恶略环境下的自适应,记个笔记,苦于没有外网的arm架构环境,内网中安装个arm类型的deb,难如登天,突然发现这个好东西。 参考引用 x86架构的Ubuntu上通过Docker运行ARM架构的系统 前提 docker已经安装好 安…...
力扣:92. 反转链表 II(Java)
目录 题目描述:示例 1:示例 2:代码实现: 题目描述: 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的…...
[less配置]vue2引入less
1、终端输入:npm install less less-loader --save-dev 2、在package.json查看是否安装less依赖 3、调用...
物理内存与虚拟内存的区别
物理内存和虚拟内存是计算机系统中重要的概念,它们有着不同的特点和作用。 物理内存: 物理内存是计算机实际存在的内存,通常指的是RAM(随机存取存储器)。物理内存直接映射到计算机的物理地址空间,可以直接被…...
MySQL数据库案例实战教程:数据类型、语法与高级查询详解
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...
操作系统——用户态与内核态、同步与异步、阻塞与阻塞
文章目录 什么是用户态与内核态同步与异步、阻塞与非阻塞四种组合方式 什么是用户态与内核态 计算机系统中,通常 CPU 执行两种不同性质的程序代码:一种是操作系统内核程序(管理程序);另一种是用户自编程序(…...
C# VSTO读取Excel单元格Value、Value2
对单个单元格的值,需要用object 对象去接 object value (object)oneCellRange.Value; object value2 (object)oneCellRange.Value2; 对矩形范围的值,需要用object[,]去接 object[,] matrixValues (object[,])matrixRange.Value; object[,] matrixV…...
如何快速从手动测试转向自动化测试
寻求具有无缝持续集成和持续交付 (CI/CD) 的高效 DevOps 管道比以往任何时候都更加重要。想象一下这样一个场景:您的软件组织显著减少了人工工作量、降低了成本,并更加自信地发布了软件更新。换句话说,通过将 Web UI 和 API 测试结合在一起&a…...
【Linux+Docker】修改Docker容器中的hosts文件
1、进入容器bash docker exec -it <container_id> bash2、安装编辑器 2.1、安装vim apt-get updateapt-get install vim2.2、安装nano apt-get install nano3、编辑hosts文件 3.1、使用vim编辑 vi /etc/hosts3.2、使用nano编辑 nano /etc/hosts4、安装ping apt-get…...
在VS Code中进行Java的单元测试
在VS Code中可以使用 Test Runner for Java扩展进行Java的测试执行和调试。 Test Runner for Java的功能 Test Runner for Java 结合 Language Support for Java by Red Hat 和 Debugger for Java这两个插件提供如下功能: 运行测试: Test Runner for …...
国内信创web中间件生态
国内信创web中间件生态 东方通 官网https://www.tongtech.com/pctype/25.html 宝蓝德 官网https://www.bessystem.com/product/0ad9b8c4d6af462b8d15723a5f25a87d/info?p101 金蝶天燕 官网 https://www.apusic.com/list-117.html 中创 官网http://www.inforbus.com…...
CSS中的writing-mode属性:解锁文本布局新维度
在网页设计的广阔天地里,CSS(层叠样式表)扮演着至关重要的角色,它赋予了我们塑造网页外观和布局的强大能力。其中,writing-mode属性是一个常被忽视但功能强大的工具,用于控制文本的书写方向和排列方式。今天…...
SQL面试题练习 —— 波峰波谷
来源:字节今日头条 目录 1 题目2 建表语句3 题解 1 题目 有如下数据,记录每天每只股票的收盘价格,请查出每只股票的波峰和波谷的日期和价格; 波峰定义:股票价格高于前一天和后一天价格时为波峰 波谷定义:股…...
检索模型预训练方法:RetroMAE
论文title:https://arxiv.org/pdf/2205.12035RetroMAE: Pre-Training Retrieval-oriented Language Models Via Masked Auto-Encoder 论文链接:https://arxiv.org/pdf/2205.12035 摘要 1.一种新的MAE工作流,编码器和解器输入进行了不同的掩…...
OpenHarmony实战开发——宿舍全屋智能开发指南
项目说明 基于OpenAtom OpenHarmony(以下简称“OpenHarmony”)、数字管家开发宿舍全屋智能,实现碰一碰开门、碰一碰开灯、碰一碰开风扇以及烟感检测。因为各项目开发流程大体相似,本文主要以碰一碰开门为例介绍如何在现有OpenHar…...
等了10年,终于迎来RTX5/RTX4全家桶开源,开源,开源! 且免费商用
我们的V4, V5, V6 ,V7开发板都配套了大量的RTX4, RTX5教程和案例,从2015年发布首版RTX4内核教程以来,已经整整10年了。 1、制作这个RTX教程和案例,其实也承受了很大的压力,因为只有RTX内核是免费商用的,中间件并不免费…...
Python 读取.shp文件并生成图幅编号
代码适用于需要处理和分析地理空间数据的场景,如城市规划、环境监测或自然资源管理,其中它可以帮助用户读取特定区域的Shapefile文件,确定其地理边界,并基于这些边界计算出按照经纬度5度间隔的图幅编号,进而用于地图制…...
【算法】位运算算法——判断字符是否唯一
题解:判断字符是否唯一(位运算算法) 目录 1.题目2.题解3.位图参考代码4.细节5.总结 1.题目 题目链接:LINK 2.题解 题解有两种方法, 一是做一个哈希数组,去查重; 二是直接用一个变量每一位来对应表示是否有这个字母…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
