简单顺序计算器

C语言题目:简单顺序计算器,用python代码解。


(笔记模板由python脚本于2024年09月27日 22:58:16创建,本篇笔记适合喜欢python的coder翻阅)


【学习的细节是欢悦的历程】


  自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
            —— 华罗庚


等风来,不如追风去……


C语言编程题目
简单顺序计算器
(用python代码写解)


本文质量分:

96 96 96

本文地址: 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

主要函数说明:

  1. split_part(expr: str) -> list

    • 功能:将输入的算式字符串拆分成数值和运算符的列表。
    • 输入:合法的算式字符串 expr
    • 输出:包含数值和运算符的列表。
  2. validate_expression(expr: str) -> bool

    • 功能:验证输入的算式字符串是否合法。
    • 输入:算式字符串 expr
    • 输出:如果算式合法,返回 True;否则抛出 ValueError 异常。
  3. calculate(expr:str) -> float

    • 功能:计算算式的结果。
    • 输入:合法的算式字符串 expr
    • 输出:计算结果,类型为浮点数。
  4. calculator(expr:str) -> int|float

    • 功能:调用 calculate 函数计算结果,并根据结果类型返回整数或保留两位小数的浮点数。
    • 输入:合法的算式字符串 expr
    • 输出:计算结果,类型为整数或浮点数。
  5. main() -> None

    • 功能:程序的入口函数,负责接收用户输入的算式,调用计算器进行计算,并输出结果。
    • 输出:无返回值,直接打印计算结果。

程序流程:

  1. 用户输入算式。
  2. 程序清屏并显示输入提示。
  3. 程序接收用户输入的算式,并进行校验。
  4. 如果算式合法,程序进行计算并输出结果。
  5. 如果算式不合法或计算过程中出现错误(如除以零),程序将抛出异常并提示用户。

注意事项:

  • 输入的算式必须是合法的,即只能包含整数和加、减、乘、除运算符,且运算符之间不能有空格。
  • 程序不支持括号,所有运算符的优先级相同,按照从左到右的顺序计算。
  • 计算结果如果为非整数,将保留两位小数。



回页目录


3、程序效果


  • 截屏图片
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述



回页目录


4、代码解读


  1. 脚本声明

    • #!/usr/bin/env python3:这是一个 Shebang 行,告诉系统使用哪个解释器来执行这个脚本。
  2. 编码声明

    • # coding: utf-8:这行声明脚本使用 UTF-8 编码,允许在代码中使用非ASCII字符。
  3. 模块导入

    • import re:导入正则表达式模块,用于字符串匹配。
  4. 函数定义

    • splitpart 函数:

      • 功能:将输入的算术表达式字符串分割成数值和运算符的列表。
      • 参数:expr(字符串类型),表示算术表达式。
      • 返回值:一个列表,包含表达式中的数值和运算符。
    • validate_expression 函数:

      • 功能:验证输入的算术表达式是否符合预期的格式。
      • 参数:expr(字符串类型),表示算术表达式。
      • 异常:如果表达式格式不正确,抛出 ValueError
    • calculate 函数:

      • 功能:计算并返回算术表达式的结果。
      • 参数:expr(字符串类型),表示算术表达式。
      • 处理流程:首先验证表达式,然后分割表达式,接着从左到右计算表达式的值。
    • calculator 函数:

      • 功能:调用 calculate 函数计算结果,并根据结果类型返回整数或保留两位小数的浮点数。
      • 参数:expr(字符串类型),表示算术表达式。
      • 返回值:计算结果,可能是整数或浮点数。
  5. 主程序逻辑

    • main 函数:

      • 功能:程序的入口点,负责与用户交互,接收输入并显示计算结果。
      • 流程:清屏,提示用户输入,计算并打印结果。
    • 异常处理:

      • 如果在执行 main 函数过程中出现 ValueError 异常,捕获该异常并打印错误信息。
  6. 程序入口

    • 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篇。


推荐条件 阅读量突破6.00k
(更多热博,请点击蓝色文字跳转翻阅)

  • 截屏图片
    在这里插入图片描述
      (此文涉及ChatPT,曾被csdn多次下架,前几日又因新发笔记被误杀而落马。躺“未过审”还不如回收站,回收站还不如永久不见。😪值此年底清扫,果断移除。留此截图,以识“曾经”。2023-12-31)



回页首


老齐漫画头像

精品文章:

来源:老齐教室


Python 入门指南【Python 3.6.3】


好文力荐:


CSDN实用技巧博文:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦幻精灵_cq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值