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', '-']

 

posted @ 2019-10-22 10:03  fly_bk  阅读(226)  评论(0编辑  收藏  举报