C语言题目:简单顺序计算器,用python代码解。
(笔记模板由python脚本于2024年09月27日 22:58:16创建,本篇笔记适合喜欢python的coder翻阅)
-
Python 官网:https://www.python.org/
-
Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单……
地址:https://lqpybook.readthedocs.io/
自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
—— 华罗庚
- My CSDN主页、My HOT博、My Python 学习个人备忘录
- 好文力荐、 老齐教室
本文质量分:
本文地址: https://blog.csdn.net/m0_57158496/
CSDN质量分查询入口:http://www.csdn.net/qc
- ◆ 简单顺序计算器
- 1、题目描述
- 1、题目描述
- 1.1 题目截屏图片
- 1.2 题目文本
- 2、程序说明
- 3、程序效果
- 4、代码解读
- 5、四个split_part拆分算式代码形式
- 6、完整源码(Python)
◆ 简单顺序计算器
1、题目描述
1、题目描述
1.1 题目截屏图片
题目描述截屏图片
【题目来源于博主MoonTinan文章“简单计算器”】
1.2 题目文本
C语言题目:
模拟简单运算器的工作。假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算。
输入格式:
输入在一行中给出一个四则运算算式,没有空格,且至少有一个操作数。遇等号”=”说明输入结 束。
输出格式:
在一行中输出算式的运算结果,或者如果除法分母为0或有非法运算符,则输出错误信息“ERROR”。
输入样例:
1+2*10-10/2=
输出样例:
10
代码长度限制:
16 KB
时间限制:
400 ms
内存限制:
64 MB
注意: 除0问题,逻辑或逻辑与问题,最后一个操作数的保存问题(使读入’='时也进行记录储存,并通过break跳出而不通过外部设定循环条件跳出),for循环条件的正序与逆序 。
2、程序说明
程序名称:简单顺序整数计算器
程序功能:
本程序模拟一个简单的计算器,能够对整数进行加、减、乘、除运算。计算器的特点是运算符优先级相同,按照从左到右的顺序进行计算。计算结果可以是整数或浮点数,如果结果不是整数,则保留两位小数。
程序文件:int-simple-calculator.py
主要函数说明:
-
split_part(expr: str) -> list
:- 功能:将输入的算式字符串拆分成数值和运算符的列表。
- 输入:合法的算式字符串
expr
。 - 输出:包含数值和运算符的列表。
-
validate_expression(expr: str) -> bool
:- 功能:验证输入的算式字符串是否合法。
- 输入:算式字符串
expr
。 - 输出:如果算式合法,返回
True
;否则抛出ValueError
异常。
-
calculate(expr:str) -> float
:- 功能:计算算式的结果。
- 输入:合法的算式字符串
expr
。 - 输出:计算结果,类型为浮点数。
-
calculator(expr:str) -> int|float
:- 功能:调用
calculate
函数计算结果,并根据结果类型返回整数或保留两位小数的浮点数。 - 输入:合法的算式字符串
expr
。 - 输出:计算结果,类型为整数或浮点数。
- 功能:调用
-
main() -> None
:- 功能:程序的入口函数,负责接收用户输入的算式,调用计算器进行计算,并输出结果。
- 输出:无返回值,直接打印计算结果。
程序流程:
- 用户输入算式。
- 程序清屏并显示输入提示。
- 程序接收用户输入的算式,并进行校验。
- 如果算式合法,程序进行计算并输出结果。
- 如果算式不合法或计算过程中出现错误(如除以零),程序将抛出异常并提示用户。
注意事项:
- 输入的算式必须是合法的,即只能包含整数和加、减、乘、除运算符,且运算符之间不能有空格。
- 程序不支持括号,所有运算符的优先级相同,按照从左到右的顺序计算。
- 计算结果如果为非整数,将保留两位小数。
3、程序效果
截屏图片
4、代码解读
-
脚本声明:
#!/usr/bin/env python3
:这是一个 Shebang 行,告诉系统使用哪个解释器来执行这个脚本。
-
编码声明:
# coding: utf-8
:这行声明脚本使用 UTF-8 编码,允许在代码中使用非ASCII字符。
-
模块导入:
import re
:导入正则表达式模块,用于字符串匹配。
-
函数定义:
-
splitpart
函数:- 功能:将输入的算术表达式字符串分割成数值和运算符的列表。
- 参数:
expr
(字符串类型),表示算术表达式。 - 返回值:一个列表,包含表达式中的数值和运算符。
-
validate_expression
函数:- 功能:验证输入的算术表达式是否符合预期的格式。
- 参数:
expr
(字符串类型),表示算术表达式。 - 异常:如果表达式格式不正确,抛出
ValueError
。
-
calculate
函数:- 功能:计算并返回算术表达式的结果。
- 参数:
expr
(字符串类型),表示算术表达式。 - 处理流程:首先验证表达式,然后分割表达式,接着从左到右计算表达式的值。
-
calculator
函数:- 功能:调用
calculate
函数计算结果,并根据结果类型返回整数或保留两位小数的浮点数。 - 参数:
expr
(字符串类型),表示算术表达式。 - 返回值:计算结果,可能是整数或浮点数。
- 功能:调用
-
-
主程序逻辑:
-
main
函数:- 功能:程序的入口点,负责与用户交互,接收输入并显示计算结果。
- 流程:清屏,提示用户输入,计算并打印结果。
-
异常处理:
- 如果在执行
main
函数过程中出现ValueError
异常,捕获该异常并打印错误信息。
- 如果在执行
-
-
程序入口:
if __name__ == '__main__':
:Python 中的常见约定,用于判断当前脚本是否作为主程序运行。- 如果是主程序,调用
main
函数。
这个代码解读更侧重于代码的结构和逻辑流程,而不是程序的功能描述。它解释了每个函数的作用、参数、返回值以及函数之间的调用关系,同时也描述了主程序如何运行和异常处理机制。
5、四个split_part拆分算式代码形式
一、
# str.splace
def split_part(expr:str) -> list:
''' 拆分算式成数值和运算符 '''
return expr.replace('+', ' + ').replace('-', ' - ').replace('*', ' * ').replace('/', ' / ').split()
ai点评
使用 str.replace
方法:
点评:
- 由于输入是经过校验的合法算式,这个方法在这种情况下是有效的,因为它假设输入不会包含额外的空格或非法字符。
- 它简单直接,易于理解和实现。
批判:
- 即使输入是经过校验的,这种方法仍然依赖于空格来分割字符串,这在其他情况下可能不是一个好习惯。
- 需要多次调用
replace
方法,尽管在这个特定场景下性能影响不大。
二、
# 手撕str.replace
def split_part(expr:str) -> list:
''' 拆分算式成数值和运算符 '''
expr = list(expr)
for i in range(len(expr)):
if expr[i] == '+':
expr[i] = ' + '
elif expr[i] == '-':
expr[i] = ' - '
elif expr[i] == '*':
expr[i] = ' * '
elif expr[i] == '/':
expr[i] = ' / '
return ''.join(expr).split()
ai点评
手动遍历字符串并替换:
点评:
- 与
str.replace
方法类似,由于输入是经过校验的,这个方法也可以正常工作。 - 它避免了使用多次
replace
方法,可能在某些情况下性能稍好。
批判:
- 与第一个方法一样,它依赖于在运算符周围添加空格来分割字符串。
- 遍历字符串并修改列表,虽然避免了多次
replace
,但性能提升有限。
三、
# 遍历字符串
def split_part(expr:str) -> list:
''' 拆分算式成数值和运算符 '''
parts = [] # 算式分拆列表
number = []
for char in expr:
if char.isdigit():
number.append(char)
else:
if number:
parts.append(''.join(number))
number = []
parts.append(char)
parts.append(''.join(number)) # 收集最后一个数字
return parts
ai点评
遍历字符串并收集数字:
点评:
- 这个方法不依赖于空格来分割字符串,而是直接处理数字和运算符,这使得它在处理算式时更为健壮。
- 它能够正确处理经过校验的合法算式。
批判:
- 对于经过校验的输入,这种方法可能比使用正则表达式更为复杂,尽管它提供了额外的健壮性。
- 性能上可能不如直接使用字符串操作。
四、
# re正则匹配
def split_part(expr: str) -> list:
''' 拆分算式成数值和运算符 '''
pattern = r'(?:^[+-]?\d+)|(?:[*/+-])|(?:\d+)' # 正则表达式,匹配数字(包括正负号)和运算符
return re.findall(pattern, expr) # 使用 re.findall 查找所有匹配项
ai点评
使用 re
正则表达式:
点评:
- 正则表达式方法提供了非常强大的模式匹配能力,可以简洁地处理复杂的字符串分割问题。
- 它能够正确处理经过校验的合法算式,且不依赖于空格。
批判:
- 对于经过校验的简单算式,使用正则表达式可能有些“大材小用”,但在处理更复杂的算式时,它的优势会非常明显。
- 正则表达式可能会对性能产生一些影响,但在这个场景下,由于算式简单,这种影响可以忽略不计。
ai总结:
考虑到你的输入是经过校验的合法算式,第一个和第二个方法在这种情况下都是可行的,并且简单直观。第三个方法提供了额外的健壮性,但可能稍微复杂一些。第四个方法(正则表达式)是最灵活和强大的,尽管对于这个特定问题可能显得有些“过度杀伤”。
在这种情况下,选择哪个方法取决于你的偏好和未来可能的需求。如果你预期算式可能会变得更复杂,或者你可能需要在其他场景中复用分割逻辑,那么使用正则表达式可能是更好的选择。如果算式始终保持简单,并且没有进一步的需求,那么第一个或第二个方法可能就足够了。
6、完整源码(Python)
(源码较长,点此跳过源码)
#!/sur/bin/nve python3
# coding: utf-8
import re
'''
C语言题目:
模拟简单运算器的工作。
假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算。
filename: int-simple-calculator.py
'''
def split_part(expr: str) -> list:
''' 拆分算式成数值和运算符 '''
pattern = r'(?:^[+-]?\d+)|(?:[*/+-])|(?:\d+)' # 正则表达式,匹配数字(包括正负号)和运算符
return re.findall(pattern, expr) # 使用 re.findall 查找所有匹配项
def validate_expression(expr: str) -> bool:
pattern = r'^[+-]?\d+(?:[+\-*/]\d+)*$' # 正则表达式:开头可以有+、-运算符一个,后接+、-、*、/运算符一个和数字组合,这样的组合可以有零个或者多个。由此通配表达式,可以涵盖本题目描述的“计算器”的所有合法表达式。
if re.fullmatch(pattern, expr):
return True
else:
raise ValueError(f"\n{'':-^42}\n\n{' 算式错误! ':^37}\n\n{'':-^42}")
def calculate(expr:str) -> float:
''' 算式计算 '''
if validate_expression(expr): # 算式校验
expr = split_part(expr) # 算式拆分
# 第一个整数处理
if expr[0].isdigit():
result = int(expr[0])
expr = expr[1:]
else:
result = -1*int(expe[1]) if expr[0]=='-' else int(expr[1])
expr = expr[2:]
# 顺序计算
n = len(expr) - 1
k = 0
while k < n:
if expr[k] == '+':
result += int(expr[k+1])
elif expr[k] == '-':
result -= int(expr[k+1])
elif expr[k] == '*':
result *= int(expr[k+1])
elif expr[k] == '/':
if int(expr[k+1])==0:
raise ValueError(f"\n{'':-^42}\n\n{' 零除错误! ':^37}\n\n{'':-^42}")
else:
result /= int(expr[k+1])
k += 2
return result
def calculate(expr:str) -> float:
''' 算式计算 '''
if validate_expression(expr): # 算式校验
expr = split_part(expr) # 算式拆分
# 第一个整数处理
if expr[0].isdigit():
result = int(expr[0])
expr = expr[1:]
else:
result = -1*int(expe[1]) if expr[0]=='-' else int(expr[1])
expr = expr[2:]
# 顺序计算
expr = [int(part) if part.isdigit() else part for part in expr] # int整数
n = len(expr) - 1
k = 0
while k < n:
if expr[k] == '+':
result += expr[k+1]
elif expr[k] == '-':
result -= expr[k+1]
elif expr[k] == '*':
result *= expr[k+1]
elif expr[k] == '/':
if expr[k+1]==0:
raise ValueError(f"\n{'':-^42}\n\n{' 零除错误! ':^37}\n\n{'':-^42}")
else:
result /= expr[k+1]
k += 2
return result
def calculator(expr:str) -> int|float:
result = calculate(expr)
return round(result, 0) if round(result, 0) == result else round(result, 2) # 计算结果非整型,保留两个小数位
def main() -> None:
clear = '\033[2J' #清屏字符串,windows系统老版本不支持
expression = input(f"{clear}{' 简单顺序整数“计算器” ':=^33}\n{'(+、-、*、/顺序计算)':^36}\n\n输入算式:").strip()
result = calculator(expression)
print(f"\n\n{'结果:':>7}{result}\n\n{'':=^42}")
if __name__ == '__main__':
try:
main()
except ValueError as e:
print(e)
上一篇: re轻松拆分四则运算expression(与ai对抵聊“算式匹配”,发现^从头匹配、(?:xxxx)非捕获组、| “交替”运算符联合使用的妙处)
下一篇:
我的HOT博:
本次共计收集 311 篇博文笔记信息,总阅读量43.82w。数据于2024年03月22日 00:50:22完成采集,用时6分2.71秒。阅读量不小于6.00k的有
7
7
7篇。
-
001
标题:让QQ群昵称色变的神奇代码
(浏览阅读 5.9w )
地址:https://blog.csdn.net/m0_57158496/article/details/122566500
点赞:25 收藏:86 评论:17
摘要:让QQ昵称色变的神奇代码。
首发:2022-01-18 19:15:08
最后编辑:2022-01-20 07:56:47 -
002
标题:Python列表(list)反序(降序)的7种实现方式
(浏览阅读 1.1w )
地址:https://blog.csdn.net/m0_57158496/article/details/128271700
点赞:8 收藏:35 评论:8
摘要:Python列表(list)反序(降序)的实现方式:原址反序,list.reverse()、list.sort();遍历,全数组遍历、1/2数组遍历;新生成列表,resersed()、sorted()、负步长切片[::-1]。
首发:2022-12-11 23:54:15
最后编辑:2023-03-20 18:13:55 -
003
标题:pandas 数据类型之 DataFrame
(浏览阅读 9.7k )
地址:https://blog.csdn.net/m0_57158496/article/details/124525814
点赞:7 收藏:36
摘要:pandas 数据类型之 DataFrame_panda dataframe。
首发:2022-05-01 13:20:17
最后编辑:2022-05-08 08:46:13 -
004
标题:个人信息提取(字符串)
(浏览阅读 8.2k )
地址:https://blog.csdn.net/m0_57158496/article/details/124244618
点赞:2 收藏:15
摘要:个人信息提取(字符串)_个人信息提取python。
首发:2022-04-18 11:07:12
最后编辑:2022-04-20 13:17:54 -
005
标题:Python字符串居中显示
(浏览阅读 7.6k )
地址:https://blog.csdn.net/m0_57158496/article/details/122163023
评论:1 -
006
标题:罗马数字转换器|罗马数字生成器
(浏览阅读 7.5k )
地址:https://blog.csdn.net/m0_57158496/article/details/122592047
摘要:罗马数字转换器|生成器。
首发:2022-01-19 23:26:42
最后编辑:2022-01-21 18:37:46 -
007
标题:回车符、换行符和回车换行符
(浏览阅读 6.0k )
地址:https://blog.csdn.net/m0_57158496/article/details/123109488
点赞:2 收藏:3
摘要:回车符、换行符和回车换行符_命令行回车符。
首发:2022-02-24 13:10:02
最后编辑:2022-02-25 20:07:40
截屏图片
(此文涉及ChatPT,曾被csdn多次下架,前几日又因新发笔记被误杀而落马。躺“未过审”还不如回收站,回收站还不如永久不见。😪值此年底清扫,果断移除。留此截图,以识“曾经”。2023-12-31)
精品文章:
- 好文力荐:齐伟书稿 《python 完全自学教程》 Free连载(已完稿并集结成书,还有PDF版本百度网盘永久分享,点击跳转免费🆓下载。)
- OPP三大特性:封装中的property
- 通过内置对象理解python'
- 正则表达式
- python中“*”的作用
- Python 完全自学手册
- 海象运算符
- Python中的 `!=`与`is not`不同
- 学习编程的正确方法
来源:老齐教室
◆ Python 入门指南【Python 3.6.3】
好文力荐:
- 全栈领域优质创作者——[寒佬](还是国内某高校学生)博文“非技术文—关于英语和如何正确的提问”,“英语”和“会提问”是编程学习的两大利器。
- 【8大编程语言的适用领域】先别着急选语言学编程,先看它们能干嘛
- 靠谱程序员的好习惯
- 大佬帅地的优质好文“函数功能、结束条件、函数等价式”三大要素让您认清递归
CSDN实用技巧博文:
- 8个好用到爆的Python实用技巧
- python忽略警告
- Python代码编写规范
- Python的docstring规范(说明文档的规范写法)