zoukankan      html  css  js  c++  java
  • python 二叉树计算器

    例子:计算1+2+3+4的值

    代码:

    class Buffer(object):
        """字符串处理函数"""
    
        def __init__(self, str_value):
            self._str_value = str_value
            self._off_set = 0
    
        def peek(self):
            if self._off_set >= len(self._str_value):
                return None
            else:
                return self._str_value[self._off_set]
    
        def advance(self):
            self._off_set += 1
    
    
    class Token(object):
        """定义节点类型,{int,2}{ope,+}"""
    
        def consum(self, buffer):
            pass
    
    
    class TokenInt(Token):
        """整数节点类型{int,2}"""
    
        def consum(self, buffer):
            accu = ""
            while True:
                ch = buffer.peek()
                if ch is None or ch not in "1234567890":
                    break
                else:
                    accu += ch
                    buffer.advance()
            if accu != "":
                return "int", int(accu)
            else:
                return None
    
    
    class TokenOperator(Token):
        """操作符接点类型,返回{ope,+}"""
    
        def consum(self, buffer):
            ch = buffer.peek()
            if ch is not None and ch in "+-":
                buffer.advance()
                return "ope", ch
            else:
                return None
    
    
    class Node(object):
        """节点"""
        pass
    
    
    class NodeInt(Node):
        """整数节点"""
    
        def __init__(self, value):
            self.value = value
    
    
    class NodeOpe(Node):
        """加减节点"""
    
        def __init__(self, kind):
            self.kind = kind
            self.left = None
            self.right = None
    
    
    def get_tokens(string):
        """根据string获取节点类型数组"""
        buffer = Buffer(string)
        tk_int = TokenInt()
        tk_ope = TokenOperator()
        tokens = []
    
        while buffer.peek():
            token = None
            for tk in (tk_int, tk_ope):
                token = tk.consum(buffer)
                if token:
                    tokens.append(token)
                    break
            if not token:
                raise ValueError("Error in syntax")
        return tokens
    
    
    def parse(tokens):
        """将tokens生成二叉树"""
        # 判断第一个是不是数字
        if tokens[0][0] != 'int':
            raise ValueError('Error in syntax')
        # 新建第一个节点
        node = NodeInt(tokens[0][1])
        # 下一个节点
        node_next = None
        # 节点类型
        node_type = tokens[0][0]
        for token in tokens[1:]:
            # 判断节点类型是否一致
            if token[0] == node_type:
                raise ValueError("error in syntax")
            node_type = token[0]
            # 判断是什么操作符
            # 如果是符号
            if token[0] == 'ope':
                node_next = NodeOpe(token[1])
                node_next.left = node
            if token[0] == 'int':
                node_next.right = NodeInt(token[1])
                node = node_next
        return node
    
    
    def calculate(node):
        """迭代求值"""
        if isinstance(node.left, NodeOpe):
            left_value = calculate(node.left)
        else:
            left_value = node.left.value
    
        if node.kind == '-':
            return left_value - node.right.value
        elif node.kind == '+':
            return left_value + node.right.value
        else:
            raise ValueError('Error in syntax')
    
    
    def evalute(node):
        """判断是否只有一个数值"""
        if isinstance(node, NodeInt):
            return node.value
        else:
            return calculate(node)
    
    
    if __name__ == '__main__':
        input_str = input("input:")
        tokens = get_tokens(input_str)
        node = parse(tokens)
        print("value is {}".format(evalute(node)))
    身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
  • 相关阅读:
    ES6 新特性
    基于.NET平台常用的框架整理
    你可能不知道的一些JavaScript 奇技淫巧
    js中apply方法的使用
    数据库中字段类型对应C#中的数据类型
    C# Socket SSL通讯笔记
    Media Types
    JS使用模板快速填充HTML控件数据 --- 自己写组件(0)
    FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解
    FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块
  • 原文地址:https://www.cnblogs.com/birdofparadise/p/8303916.html
Copyright © 2011-2022 走看看