• 05_2.栈的应用--表达式的计算和变换


    后缀表达式的计算:

    class ESStack(SStack):
        """SStack参考05.栈"""
        def depth(self):
            return len(self._elems)
    
    
    def suf_exp_evaluator(exp):
        """后缀表达式计算"""
        operators = "+-*/"
        st = ESStack()
        for x in exp:
            if x not in operators:
                st.push(float(x))
                continue
            if st.depth() < 2:
                raise SyntaxError("Short of operand(s).")
            b = st.pop()
            a = st.pop()
            if x == "+":
                c = a + b
            elif x == "-":
                c = a - b
            elif x == "*":
                c = a * b
            elif x == "/":
                c = a / b
            else:
                break
            st.push(c)
        if st.depth() == 1:
            return st.pop()
        raise SyntaxError("Extra operand(s).")
    
    
    def suffix_exp_evaluator(line):
        """表达式的每一项用空格隔开
        如:计算11+12
        应输入:11 12 +
        """
        return suf_exp_evaluator(line.split())
    
    
    def suffix_exp_calculator():
        """表达式交互"""
        while 1:
            try:
                line = input("Suffix Expression:")
                if line == "exit":return
                res = suffix_exp_evaluator(line)
                print(res)
            except Exception as ex:
                print("Error:", type(ex), ex.args)
    
    
    if __name__ == '__main__':
        suffix_exp_calculator()

    中缀表达式转换为后缀表达式:

    def trans_infix_suffix(line):
        """中缀表达式转换为后缀表达式"""
        infix_operators = "+-*/()"
        priority = {"(": 1, "+": 3, "-": 3, "*": 5, "/": 5}
        st = SStack()
        exp = []
        for x in tokens(line):
            if x not in infix_operators:  # 遇到操作数时,将加入exp;
                exp.append(x)
            elif st.is_empty() or x == '(':  # 如果st为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈
                st.push(x)
            elif x == ')':  # 遇到右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
                while not st.is_empty() and st.top() != '(':
                    exp.append(st.pop())
                if st.is_empty():
                    raise SyntaxError("Missing '('.")
                st.pop()
            else:  # 若x优先级比栈顶运算符的高,直接将运算符压入栈,否则将栈顶的运算符弹出并加入到exp中,重复比较x与栈顶
                while (not st.is_empty() and priority[st.top()] >= priority[x]):
                    exp.append(st.pop())
                st.push(x)
        while not st.is_empty():
            if st.top() == '(':
                raise SyntaxError("Extra '('.")
            exp.append(st.pop())  # 栈中剩余的运算符依次弹出并加入exp
        return exp
    
    
    def tokens(line):
        """ 生成器函数
            逐一生成line中的一个个项,不处理一元运算符,也不能处理带符号的浮点数
        """
        infix_operators = "+-*/()"
        line = line.strip()
        i, llen = 0, len(line)
        while i < llen:
            while line[i].isspace():  # 检测字符串是否只由空格组成
                i += 1
            if i >= llen:
                break
            if line[i] in infix_operators:  # 运算符的情况
                yield line[i]
                i += 1
                continue
            j = i + 1  # 下面处理运算对象
            # 数字是按空格分开的 如:11 就是11  ,1  1 就会处理成1与1
            while (j < llen and not line[j].isspace() and line[j] not in infix_operators):
                # 如果出现E或e,后面可以有一个负的指数部分 2e2 就是2*100
                if ((line[j] == 'e' or line[j] == 'E') and j + 1 < llen and line[j + 1] == '-'):
                    j += 1
                j += 1
            yield line[i:j]
            i = j
    
    
    def test_trans_infix_suffix(s):
        print(s)  # 中缀表达式
        print(trans_infix_suffix(s))  # 后缀表法式
        # 调用后缀表法式计算函数计算结果
        print("Value:", suf_exp_evaluator(trans_infix_suffix(s)))  # 计算结果
    
    
    if __name__ == '__main__':
        # suffix_exp_calculator()
        test_trans_infix_suffix("10*(3e-1 + 1) - 1 ")  # 12.0
        # 10*(3e-1 + 1) - 1
        # ['10', '3e-1', '1', '+', '*', '1', '-']
  • 相关阅读:
    分享一个文件的工具类
    关于itext生成pdf的新的demo(包含简单的提取txt文件的内容 和xml内容转化为pdf)
    全文检索的Demo
    dom4j操作xml的demo
    利用Java获取ip地址
    利用htmlparser读取html文档的内容
    关于pdfbox操作pdf的分享链接手长
    poi读取word的内容
    基于NPOI对Excel进行简单的操作
    “尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。”
  • 原文地址:https://www.cnblogs.com/fly-book/p/11718143.html
Copyright © 2020-2023  润新知