zoukankan      html  css  js  c++  java
  • 设计模式之解释器模式

    from abc import ABCMeta, abstractmethod
    
    
    # 解释器模式:定义一个语言,定义它的文法的一种表示;并定义一个编辑器,该解释器使用文法来解释语言中的文法
    class Expression(metaclass=ABCMeta):
        """抽象表达式"""
         @abstractmethod
         def interpreter(self, var):
             pass
    
    
    class VarExpression(Expression):
        """变量解析器"""
        def __init__(self, key):
            self.__key = key
    
        def interpreter(self, var):
            return var.get(self.__key)
    
    
    class SymbolExpression(Expression):
        """运算符解析器,运算符的抽象类"""
        def __init__(self, left, right):
            self._left = left
            self._right = right
    
        
    class AddExpression(SymbolExpression):
        """加法解析器"""
        def __init__(self, left, right):
            super().__init__(left, right)
    
        def interpreter(self, var):
            return self._left.interpreter(var) + self._right.interpreter(var)
    
    
    class SubExpression(SymbolExpression):
        """减法解析器"""
        def __init__(self, left, right):
            super().__init__(left, right)
    
        def interpreter(self, var):
            return self._left.interpreter(var) - self._right.interpreter(var)
    
    
    class Stack:
        """封装一个堆栈类"""
        def __init__(self):
            self._items = []
    
        def isEmpty(self):
            return len(self._items) == 0
    
        def push(self, item):
            return self._items.append(item)
    
        def pop(self):
            return self._items.pop()
    
        def peek(self):
            if not self.isEmpty():
                return self._items[len(self._items) - 1]
    
        def size(self):
            return len(self._items)
    
    
    class Calculator:
        """计算器"""
        def __init__(self, text):
            self.__expression = self.parseText(text)
    
        def parseText(self, expText):
            # 定义一个栈,处理运算的先后顺序
            stack = Stack()
            left = right = None
            idx = 0
            while idx < len(expText):
                if(expText[idx] == "+"):
                    left = stack.pop()
                    idx += 1
                    right = VarExpression(expText[idx])
                    stack.push(AddExpression(left, right))
                elif (expText[idx] == "-"):
                    left = stack.pop()
                    idx += 1
                    right = VarExpression(expText[idx])
                    stack.push(SubExpression(left, right))
                else:
                    stack.push(VarExpression(expText[idx]))
                idx += 1
            return stack.pop()
    
        def run(self, var):
            return self.__expression.interpreter(var)
    
    
    def testCalculator():
        # 获取表达式
        expStr = input("请输入表达式:")
        # 获取各参数的键值对
        newExp, expressionMap = getMapValue(expStr)
    
        calculator = Calculator(newExp)
    
        result = calculator.run(expressionMap)
    
        print("运算结果为:" + expStr + "=" + str(result))
    
    
    def getMapValue(expStr):
        preIdx = 0
        expressionMap = {}
        newExp = []
        for i in range(0, len(expStr)):
            if (expStr[i] == "+" or expStr[i] == "-"):
                key = expStr[preIdx:i]
                key = key.strip()
                newExp.append(key)
                newExp.append(expStr[i])
                var = input("请输入参数" + key + "的值:")
                var = var.strip()
                expressionMap[key] = float("var")
                preIdx = i + 1
        # 处理最后一个参数
        key = expStr[preIdx:len(expStr)]
        key = key.strip()
        newExp.append(key)
        var = input("请输入参数" + key + "的值:")
        var = var.strip()
        expressionMap[key] = float("var")
        return newExp, expressionMap
  • 相关阅读:
    树的子结构(剑指offer_26)
    合并两个排序的链表(剑指offer_25)
    反转链表(剑指offer_24)多看多思多想
    链表中环的入口结点(剑指offer_23)
    链表中倒数第k个节点
    调整数组顺序使奇数位于偶数前面(剑指offer_21)
    表示数值的字符串(剑指offer_20)
    1676. 跳石头
    1670. 回合制游戏
    1667. 区间统计(回顾)
  • 原文地址:https://www.cnblogs.com/loveprogramme/p/13170831.html
Copyright © 2011-2022 走看看