Python:表达式的计算和变换

class StackUnderflow(ValueError):
    pass


class SStack(): 
    def __init__(self):
        self._elems = []
    def is_empty(self):
        return self._elems == []
    def top(self):
        if self._elems == []:
            raise StackUnderflow
        return self._elems[len(self._elems)-1]
    def push(self, elem):
        self._elems.append(elem)
    def pop(self):
        if self._elems == []:
            raise StackUnderflow
        return self._elems.pop()


class ESStack(SStack):  #可以检查深度的栈
    def depth(self):
        return len(self._elems)


################################################
####### Suffix expression evaluator ############


def suffix_exp_evaluator(line):
    return suf_exp_evaluator(line.split())

def suf_exp_evaluator(exp):
    """exp is a list of items representing a suffix expression.
    This function evaluates it and return its value.
    """
    operators = "+-*/" 
    st = ESStack()
    for x in exp:
        if not x in operators: 
            st.push(float(x))
            continue
        if st.depth() < 2: 
            raise SyntaxError("Short of operand(s).")
        a = st.pop()    # second argument
        b = st.pop()    # first argument
        if x == "+":
            c = b + a
        elif x == "-":
            c = b - a
        elif x == "*":
            c = b * a
        elif x == "/":
            if a == 0: raise ZeroDivisionError
            c = b / a
        else:
            pass        # This branch is not possible
        st.push(c)
    if st.depth() == 1:
        return st.pop()
    raise SyntaxError("Extra operand(s).")
    # end suf_exp_evaluator


def suffix_exp_calculator():
    """Repeatly ask for expression input until an 'end'."""
    while True:
        try:
            line = input("Suffix Expression: ")
            if line == "end":
                return
            res = suffix_exp_evaluator(line)
            print(res)
        except Exception as ex:
            print("Error:", type(ex), ex.args)



#####################################################
##### Transform infix expression to suffix expression


priority = {"(":1, "+":3, "-":3, "*":5, "/":5}
infix_operators = "+-*/()"


def tokens(line):
    """ This function cannot deal with signed numbers,
    nor unary operators.
    """
    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
        while (j < llen and not line[j].isspace() and 
               line[j] not in infix_operators):
            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 trans_infix_suffix(line):
    st = SStack()
    llen = len(line)
    exp = []
    for x in tokens(line):
        if x not in infix_operators:
            exp.append(x)
        elif st.is_empty() or x == '(':
            st.push(x)
        elif x == ')':
            while not st.is_empty() and st.top() != "(":
                exp.append(st.pop())
            if st.is_empty():
                raise SyntaxError("Missing \'(\'.")
            st.pop() # discard left parethesis
        else: # consider all ops left-associative
            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 \'(\' in expression.")
        exp.append(st.pop())
    return exp


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值