侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python实现简单的四则运算计算器

Python  /  管理员 发布于 7年前   527

一、算法

     1、算法的主要思想就是将一个中缀表达式(Infix expression)转换成便于处理的后缀表达式(Postfix expression),然后借助于栈这个简单的数据结构,计算出表达式的结果。

     2、关于如何讲普通的表达式转换成后缀表达式,以及如何处理后缀表达式并计算出结果的具体算法描述不在此叙述了,书上有详细的说明。

二、简易计算器

使用说明

使用该计算器类的简单示例如下:

# usagec = Calculator()print('result: {:f}'.formart(c.get_result('1.11+2.22-3.33*4.44/5.55')))# output:result: 0.666000

测试案例

为了对这个计算器进行有效地检验,设计了几组测试案例,测试结果如下:

Test No.1: (1.11) = 1.110000Test No.2: 1.11+2.22-3.33*4.44/5.55 = 0.666000Test No.3: 1.11+(2.22-3.33)*4.44/5.55 = 0.222000Test No.4: 1.11+(2.22-3.33)*(4.44+5.55)/6.66 = -0.555000Test No.5: 1.11*((2.22-3.33)*(4.44+5.55))/(6.66+7.77) = -0.852992Test No.6: (1.11+2.22)*(3.33+4.44)/5.55*6.66 = 31.048920Test No.7: (1.11-2.22)/(3.33+4.44)/5.55*(6.66+7.77)/(8.88) = -0.041828Test No.8: Error: (1.11+2.22)*(3.33+4.44: missing ")", please check your expressionTest No.9: Error: (1.11+2.22)*3.33/0+(34-45): divisor cannot be zeroTest No.10: Error: 12+89^7: invalid character: ^

实现代码

栈的实现

栈实际上就是一个被限制操作的表,所有的操作只能在栈的顶端(入栈、出栈等),以下是使用Python代码实现的简单的栈:

class Stack(object):  """  The structure of a Stack.  The user don't have to know the definition.  """  def __init__(self):    self.__container = list()  def __is_empty(self):    """    Test if the stack is empty or not    :return: True or False    """    return len(self.__container) == 0  def push(self, element):    """    Add a new element to the stack    :param element: the element you want to add    :return: None    """    self.__container.append(element)  def top(self):    """    Get the top element of the stack    :return: top element    """    if self.__is_empty():      return None    return self.__container[-1]  def pop(self):    """    Remove the top element of the stack    :return: None or the top element of the stack    """    return None if self.__is_empty() else self.__container.pop()  def clear(self):    """    We'll make an empty stack    :return: self    """    self.__container.clear()    return self

计算器类的实现

在计算器类中,我们将表达式的合法性验证单独放在一个函数中完成,但是实际上如果需要,也可以直接放在中缀表达式转后缀表达式的函数中实现,这样只需要一次遍历表达式即可同时完成验证和转换工作。但是为了保持结构清晰,还是分开来实现比较好,每个函数尽可能最好一件事情才是比较实在的。

在该计算器类中,有很多种极端的情况没有被考虑进去,因为那样的话整个实现的代码会更多。不过,可以在后期为整个类继续扩展,添加新的功能也是可以的。目前实现的就是主要框架,包括基本的错误检测和运算,重点时学习运用栈这个看似简单却强大的数据结构解决问题。

class Calculator(object):  """  A simple calculator, just for fun  """  def __init__(self):    self.__exp = ''  def __validate(self):    """    We have to make sure the expression is legal.    1. We only accept the `()` to specify the priority of a sub-expression. Notes: `[ {` and `] }` will be    replaced by `(` and `)` respectively.    2. Valid characters should be `+`, `-`, `*`, `/`, `(`, `)` and numbers(int, float)    - Invalid expression examples, but we can only handle the 4th case. The implementation will    be much more sophisticated if we want to handle all the possible cases.:      1. `a+b-+c`      2. `a+b+-`      3. `a+(b+c`      4. `a+(+b-)`      5. etc    :return: True or False    """    if not isinstance(self.__exp, str):      print('Error: {}: expression should be a string'.format(self.__exp))      return False    # Save the non-space expression    val_exp = ''    s = Stack()    for x in self.__exp:      # We should ignore the space characters      if x == ' ':        continue      if self.__is_bracket(x) or self.__is_digit(x) or self.__is_operators(x) \          or x == '.':        if x == '(':          s.push(x)        elif x == ')':          s.pop()        val_exp += x      else:        print('Error: {}: invalid character: {}'.format(self.__exp, x))        return False    if s.top():      print('Error: {}: missing ")", please check your expression'.format(self.__exp))      return False    self.__exp = val_exp    return True  def __convert2postfix_exp(self):    """    Convert the infix expression to a postfix expression    :return: the converted expression    """    # highest priority: ()    # middle: * /    # lowest: + -    converted_exp = ''    stk = Stack()    for x in self.__exp:      if self.__is_digit(x) or x == '.':        converted_exp += x      elif self.__is_operators(x):        converted_exp += ' '        tp = stk.top()        if tp:          if tp == '(':stk.push(x)continue          x_pri = self.__get_priority(x)          tp_pri = self.__get_priority(tp)          if x_pri > tp_pri:stk.push(x)          elif x_pri == tp_pri:converted_exp += stk.pop() + ' 'stk.push(x)          else:while stk.top():  if self.__get_priority(stk.top()) != x_pri:    converted_exp += stk.pop() + ' '  else:    breakstk.push(x)        else:          stk.push(x)      elif self.__is_bracket(x):        converted_exp += ' '        if x == '(':          stk.push(x)        else:          while stk.top() and stk.top() != '(':converted_exp += stk.pop() + ' '          stk.pop()    # pop all the operators    while stk.top():      converted_exp += ' ' + stk.pop() + ' '    return converted_exp  def __get_result(self, operand_2, operand_1, operator):    if operator == '+':      return operand_1 + operand_2    elif operator == '-':      return operand_1 - operand_2    elif operator == '*':      return operand_1 * operand_2    elif operator == '/':      if operand_2 != 0:        return operand_1 / operand_2      else:        print('Error: {}: divisor cannot be zero'.format(self.__exp))        return None  def __calc_postfix_exp(self, exp):    """    Get the result from a converted postfix expression    e.g. 6 5 2 3 + 8 * + 3 + *    :return: result    """    assert isinstance(exp, str)    stk = Stack()    exp_split = exp.strip().split()    for x in exp_split:      if self.__is_operators(x):        # pop two top numbers in the stack        r = self.__get_result(stk.pop(), stk.pop(), x)        if r is None:          return None        else:          stk.push(r)      else:        # push the converted number to the stack        stk.push(float(x))    return stk.pop()  def __calc(self):    """    Try to get the result of the expression    :return: None or result    """    # Validate    if self.__validate():      # Convert, then run the algorithm to get the result      return self.__calc_postfix_exp(self.__convert2postfix_exp())    else:      return None  def get_result(self, expression):    """    Get the result of an expression    Suppose we have got a valid expression    :return: None or result    """    self.__exp = expression.strip()    return self.__calc()  """  Utilities  """  @staticmethod  def __is_operators(x):    return x in ['+', '-', '*', '/']  @staticmethod  def __is_bracket(x):    return x in ['(', ')']  @staticmethod  def __is_digit(x):    return x.isdigit()  @staticmethod  def __get_priority(op):    if op in ['+', '-']:      return 0    elif op in ['*', '/']:      return 1

总结

以上就是利用Python实现简单四则运算计算器的全部内容,希望本文的内容对大家的学习或者工作能有所帮助,如果有疑问大家可以留言交流。

参考

《数据结构与算法(C语言)》上相关章节算法描述


  • 上一条:
    用Python将动态GIF图片倒放播放的方法
    下一条:
    利用Python命令行传递实例化对象的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客