Python 設計一個簡單的計算器


設計目標

實現加減乘除及拓號優先級解析

用戶輸入'1 - 2 * ( (6-3 +(-5/5)*(9-2*3/3 + 7/3*7/4*12 +10 * 5/5 )) - (-4*3)/ (12-3*2) )'等類似公式后,

必須自己解析里面的(),+,-,*,/符號和公式,運算后得出結果,結果必須與真實的計算器所得出的結果一致  

流程圖:

代碼:

 1、主文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/10/18 22:26
# @Author  : Evescn
# @Site    : 
# @File    : mian.py
# @Software: PyCharm

import re


def multi_or_divi(string):
    # 乘除法函數
    # 去掉括號
    calc_list = re.search("[^()]+", string)
    # 以乘除符號分割
    sub_calc_list = re.split("[*/]", calc_list.group())
    # 獲取到字符串中的乘除符號
    sub_operator_list = re.findall("[*/]", calc_list.group())
    sub_res = None
    for index in range(len(sub_calc_list)):
        if sub_res:
            if sub_operator_list[index-1] == "*":
                sub_res *= float(sub_calc_list[index])
            else:
                sub_res /= float(sub_calc_list[index])
        else:
            sub_res = float(sub_calc_list[index])
    return float(sub_res)


def add_or_sub(string):
    # 加減法函數
    # 去掉括號
    calc_list = re.search("[^()]+", string)
    # 以加減符號分割
    sub_calc_list = re.split("[+-]", calc_list.group())
    # 獲取到字符串中的加減符號
    sub_operator_list = re.findall("[+-]", calc_list.group())
    # 如果字符串已減號開頭,需要特殊處理
    if re.match("[-+]", calc_list.group()):
        if sub_operator_list[0] == "-":
            sub_calc_list[1] = -float(sub_calc_list[1])
        # 對sub_operator_list和sub_calc_list進行字符串切割,或者到正確數據
        sub_operator_list = sub_operator_list[1:]
        sub_calc_list = sub_calc_list[1:]
        # 對字符串切割后,如何sub_calc_list為空,表示傳過來的數為-X,直接返回sub_calc_list[0]即可,無需乘除運算
        if len(sub_operator_list) == 0:
            return sub_calc_list[0]
    sub_res = None
    for index in range(len(sub_calc_list)):
        if sub_res:
            if sub_operator_list[index-1] == "+":
                sub_res += float(sub_calc_list[index])
            else:
                sub_res -= float(sub_calc_list[index])
        else:
            sub_res = float(sub_calc_list[index])
    return float(sub_res)


def deal_minus_issue(ret):
    # 處理減法字符串
    # 創建一個新字符串用於返回處理后的字符串
    new_ret = []
    for index, item in enumerate(ret):
        if item.endswith("*") or item.endswith("/"):
            new_ret.append("%s-%s" %(ret[index], ret[index+1]))
        elif re.search("[*/]", ret[index]):
            new_ret.append(ret[index])
    return new_ret


def main():
    # 輸入字符串
    a = '1 - 2 * ( (6-3 +(-5/5)*(9-2*3/3 + 7/3*7/4*12 +10 * 5/5 )) - (-4*3)/ (12-3*2) )'
    # a = '+(-40/5+3*(-12))'
    # 去空格
    a = a.replace(" ", "")
    # 設置循環退出的條件
    count = 2
    while True and count > 0:
        # 最內行括號
        calc_list = re.search(r'\([^()]+\)', a)
        if calc_list:
            # 如果能取到括號,把正則匹配結果賦值給calc_list_value
            calc_list_value = calc_list.group()
        else:
            # 如果不能取到括號,說明已經沒有括號了,這只有加減乘除,對多只需要2次計算即可得出結果
            # 把a字符串賦值給calc_list_value
            count -= 1
            calc_list_value = a
        if "+" in calc_list_value or "-" in calc_list_value:
            if "*" in calc_list_value or "/" in calc_list_value:
                # 去掉括號以便以加減符號分割字符串
                calc_list1 = re.findall(r'[^()]+', calc_list_value)
                # 以加減符號去分割
                calc_list2 = re.split(r'[-+]', calc_list1[0])
                # 調用處理減法字符串函數,處理下*-或者/-這類問題
                calc_list2 = deal_minus_issue(calc_list2)
                # 返回后的calc_list列表只有包含乘除的式子
                for item in calc_list2:
                    # 對每一個乘除調用乘除函數
                    value = multi_or_divi(item)
                    # 把計算后的結果替換掉原來的值
                    a = a.replace(item, str(value))
                    # 處理下字符串中出現的++或+-問題
                    a = a.replace("+-", "-")
                    a = a.replace("--", "+")
            else:
                # 式子中沒有乘除符號,那就只有加減符號,調用加減函數
                value = add_or_sub(calc_list_value)
                # 把計算后的結果替換掉原來的值
                a = a.replace(calc_list_value, str(value))
                # 處理下字符串中出現的++或+-問題
                a = a.replace("+-", "-")
                a = a.replace("--", "+")
        else:
            if "*" in calc_list_value or "/" in calc_list_value:
                # 式子中沒有加減符號,那就只有乘除符號,調用處理減法字符串函數,處理下*-或者/-這類問題
                value = multi_or_divi(calc_list_value)
                # 把計算后的結果替換掉原來的值
                a = a.replace(calc_list_value, str(value))
                # 處理下字符串中出現的++或+-問題
                a = a.replace("+-", "-")
                a = a.replace("--", "+")
        print("a:", a)

if __name__ == '__main__':
    main()  

 2、運行結果

a: 1-2*((6-3+(-1.0)*(9-2*3/3+7/3*7/4*12+10*1.0))-(-4*3)/(12-3*2))
a: 1-2*((6-3-1.0*(9-2*3/3+7/3*7/4*12+10*1.0))-(-4*3)/(12-3*2))
a: 1-2*((6-3-1.0*(9-2.0+49.00000000000001+10.0))-(-4*3)/(12-3*2))
a: 1-2*((6-3-1.0*66.0)-(-4*3)/(12-3*2))
a: 1-2*((6-3-66.0)-(-4*3)/(12-3*2))
a: 1-2*(-63.0-(-4*3)/(12-3*2))
a: 1-2*(-63.0-(-12.0)/(12-3*2))
a: 1-2*(-63.0+12.0/(12-3*2))
a: 1-2*(-63.0+12.0/(12-6.0))
a: 1-2*(-63.0+12.0/6.0)
a: 1-2*(-63.0+2.0)
a: 1-2*-61.0
a: 1+122.0
a: 123.0  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM