模拟计算器

#coding:utf-8
#Author:Mr Zhi
"""
模拟计算器开发:
实现加减乘除及拓号优先级解析
用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,
必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,
结果必须与真实的计算器所得出的结果一致
"""
# -*-coding:utf8-*-
import re
‘‘‘乘除运算函数‘‘‘
def multiply_divide(num):
    while re.search("-?\d+\.?\d*[\*\/]-?\d+\.?\d*",num): #当有*/运算时循环
        ret = re.search("-?\d+\.?\d*[\*\/]-?\d+\.?\d*",num).group() #获取包含*/算式
        if re.search("-?\d+\.?\d*\*-?\d+\.?\d*",ret): #是*的时候
            n1,n2 = re.split("\*",ret) #以*号拆分两边的数字
            multiply = float(n1)*float(n2)  #得到数字进行运算
            if re.search("-\d+\.?\d*\*-\d+\.?\d*",num): #两负相乘的正,得加上+
                num = re.sub("-?\d+\.?\d*\*-?\d+\.?\d*",("+"+str(multiply)),num,1) #替换刚算的公式
                return multiply_divide(num) #继续递归
            else:
                num = re.sub("-?\d+\.?\d*\*-?\d+\.?\d*", str(multiply), num, 1) #一般正常情况下替换
                return multiply_divide(num)
        else: #是/的时候
            n1,n2 = re.split("\/",ret) #以/分割两边的数字
            shang = float(n1)/float(n2) #得到数字进行运算
            num = re.sub("-?\d+\.?\d*\/-?\d+\.?\d*",str(shang),num,1) #一般正常情况下替换
            return multiply_divide(num) #继续递归
    else: #没有*/的时候
        return num #返回算的结果
‘‘‘加减运算函数‘‘‘
def add_subtract(num):
    while re.search("-?\d+\.?\d*[\+\-]-?\d+\.?\d*",num): #当有+-运算时循环
        ret = re.search("-?\d+\.?\d*[\+\-]-?\d+\.?\d*",num).group() #获取包含+-*运算的算式
        if re.search("-?\d+\.?\d*\+-?\d+\.?\d*",ret): #是+的时候
            n1,n2 = re.split("\+",ret) #以+分割两边的数字
            he = float(n1)+float(n2) #得到数字进行运算
            num = re.sub("-?\d+\.?\d*\+-?\d+\.?\d*",str(he),num,1) #替换刚算的公式
            return add_subtract(num)
        else:
            n1, n2 = re.split("-", ret,1)  # 以-分割两边的数字
            if n1 == "": #n1分割为空时,说明-号在开头
                n1,n2 = re.split("-",n2) #重新分割上面n2的结果
                cha = -float(n1)-float(n2) #得到数字进行运算,注意前面得加上-号
            else : #不是-开头的时候
                cha = float(n1) - float(n2)  # 得到数字进行运算
            num = re.sub("-?\d+\.?\d*--?\d+\.?\d*",str(cha),num,1) #替换刚算的公式
            return add_subtract(num) #继续递归
    else: #没有+-的时候
        return num #返回算的结果
‘‘‘格式输出‘‘‘
def form(res,sums):
    res = re.sub("\(|\)", "", res) #去掉括号
    ret = re.sub("\([^()]+\)",res,sums,1) #把括号里的公式替换成结果
    ret = re.sub("\+\+|--", "+", ret) #统一运算符,++为+,--为+
    ret = re.sub("\+-|-\+", "-", ret) #统一运算符,+-为-,-+为-
    return ret #返回结果
‘‘‘运算规则‘‘‘
def calc(num):
    print(num)
    if re.search("\([^()]+\)",num): #有括号先算
        ret = re.search("\([^()]+\)", num).group() #获取括号里的公式
        res = add_subtract(multiply_divide(ret)) #在括号里先算乘除,后算加减
        return calc(form(res, num)) #将格式化后的结果传给calc函数递归
    else: #没有括号的时候
        res = add_subtract(multiply_divide(num)) #先算乘除,后算加减
        return res
‘‘‘用户交互模式‘‘‘
while True:
    input_str = input("\033[38;1m请输入您要计算的内容(q退出)>>>>:\033[0m")
    if input_str == "q":
        exit("已退出,欢迎下次使用")
    ret = calc(re.sub(" ","",input_str))
    print("最终结果:","\033[35;1m%s\033[0m"%(ret))
时间: 2024-10-11 06:05:05

模拟计算器的相关文章

模拟计算器进行四则运算(同等优先级)(第2届第3题)

题目要求 问题描述:模拟计算器进行四则运算.假设只有+.-.*./.=五种运算符,且它们优先级相等.输入=后会显示计算结果. 样例输入:8.5+0.5*2.5= 样例输出:22.5 解决方案 比起需要考虑优先级,且有多种运算符的题目,这个问题显然要简单地多,直接读取输入并进行分析,然后再计算即可. 源码示例 结果展示 小结 题目虽简单,但是还要考虑细节,比如第一个数为负数的情况.另外本示范代码未对异常输入做检查,所以如果是写严谨的程序,为了保证健壮性,必须进行细致的错误检查.

hdu 5475 模拟计算器乘除 (2015上海网赛F题 线段树)

给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成1利用线段树的性质,对整个1~n的区间进行维护,每次输出sum[1]的值即可 Sample Input110 10000000001 22 11 21 102 32 41 61 71 122 7 Sample OutputCase #1:2122010164250484 1 # include <i

【C语言】 模拟计算器

#include <stdio.h> #include <stdlib.h> int _add(int a, int b) {     return a + b; } int _sub(int a, int b) {     return a - b; } int _mul(int a, int b) {     return a*b; } int _div(int a, int b) {     if (b == 0)     { printf("除数位0\n"

模拟计算器:一个带加减乘除和括号的表达式 求值

//整数,加,减,乘,除,多重小括号表达式的求值,例如 -1+(2-(3+4)/7)*5,(不带输入检查): #include <sstream> #include <iostream> #include <string> using namespace std; int sToI(string s); string iToS(int myInt); string sCalculate(string s1, string s2, char opr); string no

hdu1237 简单计算器 (模拟+栈)

简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15075    Accepted Submission(s): 5132 Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,

汇编计算器

开学第一周完成的汇编计算器:前后一共写了很多版本,下面是俩个版本: by  hfut  叶泽坤 冯弘承 许金龙 宋彬彬. 基础功能完善版: stack segment stack db 1024 dup(?) stack ends data segment LedMap db 0c0h,0f9h,0a4h,0b0h,099h,092h,082h,0f8h ;0 1 2 3 4..... db 080h,090h,088h,083h,0c6h,0a1h,086h,08eh KeyTable db

linux BC命令行计算器

1. 基本用法: $ bc <<< 5*4 20 $ bc <<< 5+4 9 $ bc <<< 5-4 1 或者 $ echo "5*4" | bc 20 $ echo "5+4" | bc 9 $ echo "5-4" | bc 1 也可以把算式写到文件里面,然后一次计算. $ cat calcFile 5+5 6+7 $ bc < calcFile 10 13 也可以使用HERE

设计模式一:简单工厂模式

概念理解: 1. 解耦:一般通过增加一些抽象层,来实现 功能提供者和功能使用者 两者的解耦隔离.而如果想要扩展功能即增加功能,只需要添加相应的相应的新的功能类,修改中间的抽象类即可,并不用修改使用者部分的代码.并且功能提供者的代码可以复用.而且使得程序更容易理解. 简单工厂模式介绍 一.什么是简单工厂模式? 简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个子类(这些子类继承  自一个父类或接口)的实例. 二.简单工厂模式包含的角色: 1.工厂角色(工厂类): 它负责创建所有

动手实现混合四则运算

一周前,我刚把邹欣老师的<构建之法>拿到手的时候,翻阅第一章就看见练习与讨论的第1题.对于编程能力不好的我,决定拿这道题目练一下手,但过了一周也没有真正动手编程,果然人天生就是惰性的,我就是个例子. 题目如下: 像阿超那样,花20分钟写一个能自动生成小学四则运算题目的程序.然后在此基础上扩展: (1)除了整数以外,还要支持真分数的四则运算. (2)程序支持判断对错,累计分数,倒计时. (3)支持多个运算符. (4)支持括号. (5)用户界面可以有用户选择用中文,英文或者日文. (6)把上面的功