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

原文地址:https://www.cnblogs.com/fly-book/p/11718143.html

时间: 2024-12-12 19:28:32

05_2.栈的应用--表达式的计算和变换的相关文章

使用栈完成算术表达式的计算

前言:本篇文章讲解如何利用栈,完成一个简单的算术表达式的计算过程.为了简单起见,首先假设操作数是整数,而运算符为四种类型:+.-.*./ 基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符. 假设:程序中定义了两个栈:operandStack(用来存放操作数).operatorStack(用于存放操作符). 在处理操作数和操作符之前,首先将它们压入栈中.当要处理一个操作符时,从operatorStack中将它弹出,然后将它应用在来自operandStack

c++用栈实现算术表达式的计算

用栈将算术表达式转换成后缀表达式的形式大家应该不陌生了,但是我在实现计算的时候却发现坑还是不少. 题目描述: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 输入描述: 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. 输出描述: 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. 示例1 输入 1 + 2 4 + 2 * 5 - 7 /

栈应用 - 后缀表达式的计算

有关栈API详情參看我的还有一篇博文:栈的链式存储 - API实现 遍历后缀表达式中的数字和符号 对于数字:进栈 对于符号: 从栈中弹出右操作数 从栈中弹出左操作数 依据符号进行运算 将运算结果压入栈中 遍历结束:栈中的唯一数字为计算结果 #include <stdio.h> #include "LinkStack.h" int isNumber3(char c) { return ('0' <= c) && (c <= '9'); } int

运用栈把算术表达式+,-,*,/,%(中缀表达式)转换成后缀表达式并且计算出值

原理: 1.首先判断是数值还是符号,如果是数值放进字符数组以#表示结束, 2.如果是符号,放进栈, 3.每个符号之间要比较优先级,如果栈顶符号优先级低,符号进栈,如果相等(即“(” “)”)出栈,栈顶符号优先级高,栈顶元素出栈进入字符数组,得到后缀表达式 4.计算后缀表达式,判断是数字还是符号.直到遇到符号,将前面的数字计算后放进栈,一直重复,知道“\0” 代码(局限用整数,因为有模运算,若要任何类型的代码,我的blog有) 1 #include <stdio.h> 2 #include &l

数据结构之栈对逆BoLand表达式的计算

后缀表达式:运算符位于操作符之后,计算机对该式是从做到右进行计算,计算过程如下例子 本章给出的是逆波兰表达式(后缀表达式)的计算Demo,为了便于计算,在给出的后缀表达式中加入了空格,并且使用list集合进行遍历,至于中缀怎么转变成后缀,后面文章 会给出案例. 代码如下: package com.ebiz.stack; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * @author

关系表达式的计算

近期在做一个项目,涉及到一些简单的规则匹配.规则的判定条件可以用关系表达式描述,形如(P1|P2)&(P3|P4).其中&是与,|是或,P1-P4是Pattern,具体的匹配条件,返回值是True或者False.为计算此表达式的值,采用中序转后序再计算表达式的值. 1. 后序表达式的生成 中序表达式转后序表达式算法: 1. 用&|()对原表达式进行拆分,得到List<String>.2. 从前往后遍历该List:    (1)如果是一个pattern,则入栈.    (

续前篇-关于逆波兰表达式的计算

相对于逆波兰表达式的转换,逆波兰表达的计算可谓简单不少. 具体计算方法参考:http://www.cnblogs.com/vpoet/p/4659546.html 这里也大致梳理一下: 1.新建一个栈将逆波兰表达式的数字依次压入栈中 2.当遇到运算符时,出栈两个数同时将运算结果压栈 3.重复步骤2直到计算计算,栈中的元素即为逆波兰表达式的计算结果. 实现如下: 1 #include <iostream> 2 #include <stack> 3 using namespace st

栈3--后缀表达式

栈3--后缀表达式 一.心得 代码的关键部分标红 二.题目及分析 后缀表达式 不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 * 三.代码及结果 1 #include <iostream> 2 #include <stack> 3 #include <string> 4 using namespace std; 5 6 stack<double&g

数据结构 栈的应用 --表达式求值

一: 中缀表达式求值  思想: 需要2个栈,运算对象栈OPND,运算符栈OPTR, 1:将栈OPND初始化为空,栈OPTR初始化为表达式的定界符# 2:扫描表达式,直到遇到结束符# 2.1:当前字符是运算对象,入栈OPND 2.2:当前字符是运算符且优先级比栈OPTR的栈顶运算符优先级高,入栈OPTR,处理下一个字符 2.3:当前字符是运算符且优先级比栈OPTR的栈顶运算符优先级低,则从栈OPND出栈2个运算对象,从栈OPTR出栈一个运算符进行运算,并将运算结果入栈OPND,处理当前字符 2.4