python练习之-计算器

学习以堆栈模式编写-计算器

堆栈特点:先进后出,

如下:

#!/opt/python3/bin/python3
# Author: yong
import re

def is_symbol(element):
    """进行判断,是否为数字,如果匹配是运算符,返回True,否则返回false"""
    res = False
    symbol=['+','-','*','/','(',')']
    if element in symbol:
        res=True
    return res

def proitry(top_sym, wait_sym):
    """优先级比较"""
    level1 = ['+','-']
    level2 = ['*','/']
    level3 = ['(']
    level4 = [')']
    # 运算符栈顶元素为:+或者-
    if top_sym in level1:
        if wait_sym in level2 or wait_sym in level3:
            return '<'
        else:
            return '>'
        # 以上是优化后的
        # if wait_sym in level1:
        #     return '>'
        # elif wait_sym in level2:  # top_sym='-', wait_sym='*'
        #     return '<'  # 无条件如占
        # elif wait_sym in level3:  # top_sym='-', wait_sym='('
        #     return '<'
        # elif wait_sym in level4:  # top_sym='-', wait_sym=')'
        #     return '>'  # 进行运算
        # else:
        #     return '>'
    # 运算符栈顶元素为:*或者/
    elif top_sym in level2:
        if wait_sym in level3:
            return '<'
        else:
            return '>'
        # if wait_sym in level1:  # top_sym='*' wait_sym='+'
        #     return '>'
        # elif wait_sym in level2:  # top_sym='*' wait_sym='*'
        #     return '>'
        # elif wait_sym in level3:  # top_sym='*' wait_sym='('
        #     return '<'
        # elif wait_sym in level4:  # top_sym='*' wait_sym=')'
        #     return '>'
        # else:
        #     return '>'
    # 运算符栈顶元素为:(
    elif top_sym in level3:
        if wait_sym in level4:  # top_sym='(' wait_sym=')',右括弧遇到左括弧,左括弧弹出
            return '='
        else:
            return '<'  # 只要栈顶元素为(,等待入栈的元素都应该无条件入占

def calculate(num1, symbol, num2):
    """实现具体的运算"""
    res = 0
    if symbol == '+':
        res = num1+num2
    elif symbol == '-':
        res = num1 - num2
    elif symbol == '*':
        res = num1 * num2
    elif symbol == '/':
        res = num1 / num2
    # print('from calculate res is [%s|%s|%s] %s' % (num1, symbol, num2, res))
    return res


def init_action(expression):
    """运算字符串进行格式化,以列表返回数字和运算符,如:['-1', '+', '2', '-', '3']"""
    expression = re.sub(' ', '',expression) # 去除空格
    init_l = [i for i in re.split('(\-\d+\.*\d*)', expression) if i]
    expression_l = []
    while True:
        if len(init_l) == 0:break
        exp=init_l.pop(0)
        if len(expression_l) == 0 and re.search('^\-\d+\.*\d*$', exp): # 匹配开头的负数
            expression_l.append(exp)
            continue
        if len(expression_l) > 0:  # 匹配运算字串中的负数
            if re.search('[\+\-\*\/\(]$',expression_l[-1]):
                expression_l.append(exp)
                continue
        new_l = [i for i in re.split('([\+\-\*\/\(\)])',exp) if i]  # 对后续的字符串进行切分
        expression_l  += new_l
    return expression_l

def main(expression_1):
    number_stack = []  # 数字栈
    symbol_stack = []   # 运算符栈
    for ele in expression_1:  # 进行迭代
        #####调试#####
        print('-'*20)
        print('数字栈',number_stack)
        print('运算符栈',symbol_stack)
        print('待入栈运算符',ele)
        ################
        ret = is_symbol(ele)
        if not ret:
            # 压入数字栈
            ele = float(ele)
            number_stack.append(ele)
        else:
            # 压入运算符栈
            while True:
                if len(symbol_stack) == 0:
                    symbol_stack.append(ele)
                    break
                res = proitry(symbol_stack[-1], ele)
                if res == '<':
                    symbol_stack.append(ele)
                    break
                elif res == '=':
                    symbol_stack.pop()
                elif res == '>':
                    symbol = symbol_stack.pop()
                    num2 = number_stack.pop()
                    num1 = number_stack.pop()
                    number_stack.append(calculate(num1,symbol,num2))
    else: # 循环执行完毕后,会剩最后一个运算,以下执行最后一次运算完成
        symbol = symbol_stack.pop()
        num2 = number_stack.pop()
        num1 = number_stack.pop()
        number_stack.append(calculate(num1, symbol, num2))
    return number_stack,symbol_stack

if __name__ == '__main__':
    expression='1+2+3*4/6'
    expression_1 = init_action(expression)
    number_stack = main(expression_1)
    print('运算最终结果:%s' % number_stack[0][0])

  

posted @ 2018-08-31 13:05  十年如一..bj  阅读(231)  评论(0编辑  收藏  举报