先走一遍,

前面很多知道点,都串起来了。

# coding = utf-8

# 使用列表实现栈的功能
class Stack:
    def __init__(self):
        self.items = []

    # 是否为空
    def is_empty(self):
        return self.items == []

    # 进栈
    def push(self, item):
        self.items.append(item)

    # 出栈
    def pop(self):
        return self.items.pop()

    # 返回栈顶值,不改变栈
    def peek(self):
        return self.items[len(self.items) - 1]

    # 返回栈长度
    def size(self):
        return len(self.items)

# 使用递归实现二叉树基本功能
class BinaryTree:
    def __init__(self, root_obj):
        self.key = root_obj
        self.left_child = None
        self.right_child = None

    def insert_left(self, new_node):
        node = BinaryTree(new_node)
        if self.left_child is None:
            self.left_child = node
        else:
            node.left_child = self.left_child
            self.left_child = node

    def insert_right(self, new_node):
        node = BinaryTree(new_node)
        if self.right_child is None:
            self.right_child = node
        else:
            node.right_child = self.right_child
            self.right_child = node

    def get_right_child(self):
        return self.right_child

    def get_left_child(self):
        return self.left_child

    def set_root_val(self, obj):
        self.key = obj

    def get_root_val(self):
        return self.key

# 建立一个算术分析树
def build_parse_tree(fp_exp):
    fp_list = fp_exp.split()
    p_stack = Stack()
    e_tree = BinaryTree('')
    p_stack.push(e_tree)
    current_tree = e_tree

    for item in fp_list:
        if item == '(':
            current_tree.insert_left('')
            p_stack.push(current_tree)
            current_tree = current_tree.get_left_child()
        elif item not in ['+', '-', '*', '/', ')']:
            current_tree.set_root_val(int(item))
            parent = p_stack.pop()
            current_tree = parent
        elif item in ['+', '-', '*', '/']:
            current_tree.set_root_val(item)
            current_tree.insert_right('')
            p_stack.push(current_tree)
            current_tree = current_tree.get_right_child()
        elif item == ')':
            current_tree = p_stack.pop()
        else:
            raise ValueError
    return e_tree

# 匹配加减乘除规则
class DoMatch:
    @staticmethod
    def add(op1, op2):
        return op1 + op2

    @staticmethod
    def sub(op1, op2):
        return op1 - op2

    @staticmethod
    def mul(op1, op2):
        return op1 * op2

    @staticmethod
    def true_div(op1, op2):
        return op1 / op2

# 算术分析式的求值
def evaluate(parse_tree):
    operator = DoMatch()
    opers = {'+': operator.add,
             '-': operator.sub,
             '*': operator.mul,
             '/': operator.true_div
             }
    left_c = parse_tree.get_left_child()
    right_c = parse_tree.get_right_child()

    if left_c and right_c:
        fn = opers[parse_tree.get_root_val()]
        return fn(evaluate(left_c), evaluate(right_c))
    else:
        return parse_tree.get_root_val()

# 前序遍历
def pre_order(tree):
    if tree:
        print(tree.get_root_val())
        pre_order(tree.get_left_child())
        pre_order(tree.get_right_child())

# 后序遍历
def post_order(tree):
    if tree:
        print(tree.get_root_val())
        post_order(tree.get_left_child())
        post_order(tree.get_right_child())

# 中序遍历
def in_order(tree):
    if tree:
        print(tree.get_root_val())
        in_order(tree.get_left_child())
        in_order(tree.get_right_child())

# 分析树打印
def print_exp(tree):
    s_val = ''
    if tree:
        s_val = '(' + str(print_exp(tree.get_left_child()))
        s_val = s_val + str(tree.get_root_val())
        s_val = s_val + str(print_exp(tree.get_right_child())) + ')'
    return s_val

pt = build_parse_tree("( ( 7 + 3 ) * ( 5 - 2 ) )")
print('=========pre_order================')
pre_order(pt)
print('=========post_order================')
post_order(pt)
print('=========in_order================')
in_order(pt)
print('=========print_exp================')
print(print_exp(pt))
print('=========evaluate================')
print(evaluate(pt))

  

=========pre_order================
*
+
7
3
-
5
2
=========post_order================
*
+
7
3
-
5
2
=========in_order================
*
+
7
3
-
5
2
=========print_exp================
(((7)+(3))*((5)-(2)))
=========evaluate================
30

  

python---数学表达式的分析树实现的更多相关文章

  1. 常用排序算法的python实现和性能分析

    常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...

  2. (转)Python数学函数

    原文:https://www.cnblogs.com/lpl1/p/7793645.html PYTHON-基础-内置函数小结----------http://www.wklken.me/posts/ ...

  3. 基于语法分析器GOLD Parser开发的数学表达式计算器

    最近发现一款文法分析神器,看完官网(http://goldparser.org/)的介绍后感觉很犀利的样子,于是就拿来测试了一番,写了一个数学表达式分析的小程序,支持的数学运算符如下所示:常规运算:+ ...

  4. 《构建之法》教学笔记——Python中的效能分析与几个问题

    <构建之法:现代软件工程>中第2章对效能分析进行了介绍,基于的工具是VSTS.由于我教授的学生中只有部分同学选修了C#,若采用书中例子讲解,学生可能理解起来比较困难.不过所有这些学生都学习 ...

  5. #8 Python数学方法

    前言 前几节了解了Python的不同数据类型,有小伙伴会问,不同的数据类型之间是否可以相互转换?肯定是可以的,本篇博文主要记录数字类型的转换,其他类型的相互转换会在下几节记录,Here we go! ...

  6. python金融与量化分析------Matplotlib(绘图和可视化)

    -----------------------------------------------------------Matplotlib:绘图和可视化------------------------ ...

  7. Python数学建模-01.新手必读

    Python 完全可以满足数学建模的需要. Python 是数学建模的最佳选择之一,而且在其它工作中也无所不能. 『Python 数学建模 @ Youcans』带你从数模小白成为国赛达人. 1. 数学 ...

  8. Python数学建模-02.数据导入

    数据导入是所有数模编程的第一步,比你想象的更重要. 先要学会一种未必最佳,但是通用.安全.简单.好学的方法. 『Python 数学建模 @ Youcans』带你从数模小白成为国赛达人. 1. 数据导入 ...

  9. 【数据结构与算法Python版学习笔记】树——二叉树的应用:解析树

    解析树(语法树) 将树用于表示语言中句子, 可以分析句子的各种语法成分, 对句子的各种成分进行处理 语法分析树 程序设计语言的编译 词法.语法检查 从语法树生成目标代码 自然语言处理 机器翻译 语义理 ...

随机推荐

  1. 1.Python_字符串_常用办法总结

    明确:对字符串的操作方法都不会改变原来字符串的值. 1.去掉空格和特殊符号 name.strip() 去掉空格和换行符 name.strip("xx") 去掉某个字符串 name. ...

  2. 【ARTS】01_20_左耳听风-20190325~20190331

    zz## ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 ...

  3. CVE-2019-0797漏洞:Windows操作系统中的新零日在攻击中被利用

    https://securelist.com/cve-2019-0797-zero-day-vulnerability/89885/ 前言 在2019年2月,卡巴实验室的自动漏洞防护(AEP)系统检测 ...

  4. HTTP协议02-请求和响应的报文构成

    HTTP协议和TCP/IP协议族内的其他众多协议相同,用于客户端与服务器之间的通信,请求访问文本或图像等资源的一端+称为客户端,而提供资源响应的一端称为服务端. 应用HTTP协议时,请求必定是客户端发 ...

  5. Git学习笔记01-安装Git

    学习的资料来自廖雪峰官方网站的Git教程,菜鸟教程的Git教程 Git是一个分布式版本控制工具,在windows上使用Git可以直接从官网下载,然后默认选项安装即可. 安装完成后,在开始菜单中找到找到 ...

  6. telnetlib 中各种 read 函数的意义

    基本原理 要明白 telnetlib 中各个 read 函数的意义,首先要了解 telnetlib 的工作原理. telnetlib 首先通过 socket 连接从网络接收数据,把数据存储到自己的 r ...

  7. python操作三大主流数据库(5)python操作mysql⑤使用Jinja2模板提取优化页面展示

    python操作mysql⑤使用Jinja2模板提取优化页面展示 在templates目录下的index.html.cat.html等页面有一些共同的元素,代码比较冗余可以使用模板提取公共代码,在各网 ...

  8. 通过flask实现web页面简单的增删改查bootstrap美化版

    通过flask实现web页面简单的增删改查bootstrap美化版 项目目录结构 [root@node1 python]# tree -L 2 . ├── animate.css ├── fileut ...

  9. Android中验证输入是否为汉字、手机号及邮箱

    1,验证是否为汉字 Code// 验证昵称 private boolean verifyNickname() { String nickname = edt_username.getText().to ...

  10. Gradle缓存目录文件命名规则

    在打开Android Studio项目的时候,会下载项目对应版本的gradle,该版本是在项目根目录下\gradle\wrapper\gradle-wrapper.properties文件中指定的: ...