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)))
身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
原文地址:https://www.cnblogs.com/birdofparadise/p/8303916.html