Python-計算器

功能: 通過輸入一個長字符串得到結果

包括函數:
format_string(string):
    將傳入的字符串string中的類似於"--","-+","+-","==","*+","/+" 格式化
calc_mul_div(string):
    對傳入的字符串進行乘法、除法計算,返回僅有加、減的表達式
calc_add_sub(string)
    對傳入的字符串進行加、減運算,返回計算結果

設計思路:
1 將表達式先進行去括號,返回不包含括號的單一表達式
2 將得到的單一表達式先進行乘、除運算,並用字符串替換的方式將計算表達式替換爲計算結果。直到表達式只剩下加、減運算符號。
3 將第二步計算的結果再進行加、減運算,並進行字符串替換,直到計算出表達式結果
4 將第三步計算的結果替換第一步的表達式。

5 只要表達式中包含"(",重複以上步驟直到表達式不包含任何括號



流程圖:


源碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re


# 格式化字符串
def format_string(string):
    string = string.replace("--", "+")
    string = string.replace("-+", "-")
    string = string.replace("++", "+")
    string = string.replace("+-", "-")
    string = string.replace("*+", "*")
    string = string.replace("/+", "/")
    string = string.replace(' ', '')
    return string


# 檢查表達式合法性
def check_expression(string):
    check_result = True
    # 括號是否匹配
    if not string.count("(") == string.count(")"):
        print("表達式錯誤,括號未閉合!")
        check_result = False
    if re.findall('[a-z]+', string.lower()):
        print("表達式錯誤,包含非法字符!")
        check_result = False
    return check_result


# 計算乘 、除法
def calc_mul_div(string):
    # 從字符串中獲取一個乘法或除法的表達式
    regular = "\d+\.{0,}\d{0,}[\*\/][\-]{0,}\d+\.{0,}\d{0,}"
    # 如果還能找到乘或除法表達式
    while re.findall(regular, string):
        # 獲取表達式
        expression = re.search(regular, string).group()

        # 如果是乘法
        if expression.count("*"):
            # 獲取要計算的兩個數
            x, y = expression.split("*")
            # 計算結果
            mul_result = str(float(x) * float(y))
            # 將計算的表達式替換爲計算結果值
            string = string.replace(expression, mul_result)
            # 格式化一下
            string = format_string(string)

        # 如果是除法
        if expression.count("/"):
            # 獲取要計算的兩個數
            x, y = expression.split("/")
            # 計算除法
            div_result = str(float(x) / float(y))
            # 用結果替換表達式
            string = string.replace(expression, div_result)
            string = format_string(string)
    return string


# 計算加、減法
def calc_add_sub(string):
    # 定義正則表達式
    add_regular = "[\-]{0,}\d+\.{0,}\d{0,}\+[\-]{0,}\d+\.{0,}\d{0,}"
    sub_regular = "[\-]{0,}\d+\.{0,}\d{0,}\-[\-]{0,}\d+\.{0,}\d{0,}"

    # 開始加法
    while re.findall(add_regular, string):
        # 把所有的加法都算完,獲取所有加法表達式
        add_list = re.findall(add_regular, string)
        for add_str in add_list:
            # 獲取兩個加法的數
            x, y = add_str.split("+")
            add_result = "+" + str(float(x) + float(y))
            string = string.replace(add_str, add_result)
        string = format_string(string)

    # 開始減法
    while re.findall(sub_regular, string):
        sub_list = re.findall(sub_regular, string)
        for sub_str in sub_list:
            numbers = sub_str.split("-")
            # -3-5的情況split會返回3個值
            if len(numbers) == 3:
                result = 0
                for v in numbers:
                    if v:
                        result -= float(v)
            else:
                x, y = numbers
                result = float(x) - float(y)
            # 替換字符串
            string = string.replace(sub_str, "+" + str(result))
        string = format_string(string)
    return string


if __name__ == "__main__":
    source = "1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"

    if check_expression(source):
        print("source: ", source)
        print("eval result: ", eval(source))

        while source.count("(") > 0:
            # 格式化
            source = format_string(source)
            # 去括號,得到括號的字符串,結果如:(30+6/3)
            strs = re.search('\(([/-]*\d+\.*\d*[\+\-\*/]+)+\d+\.*\d*\)', source).group()
            # 將括號的表達式進行乘、除運算
            replace_str = calc_mul_div(strs)
            # 將運算的結果在進行加、減運算
            replace_str = calc_add_sub(replace_str)
            # 將括號的字符串替換爲計算結果,結果包含(),替換時去掉():[1:-1]
            source = format_string(source.replace(strs, replace_str[1:-1]))

        else:
            # 沒有括號就到最後單一表達式了
            replace_str = calc_mul_div(source)
            # 算乘除
            replace_str = calc_add_sub(replace_str)
            # 算加減
            source = source.replace(source, replace_str)
        print("my result: ", source.replace("+", ""))






發佈了35 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章