利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# learn <<Problem Solving with Algorithms and Data Structures>>
# Release 3.0
# chengang882 @ 2016-12-20
# 它可以将常见的中缀表达式转换成后缀表达式,并计算这个表达示的值
# Completed implementation of a stack ADT

#数据结构
class Stack(object):
    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)

# 实现中缀表达式转换为后缀表达式
def infix_to_postfix(infix_expr):
    prec = {}
    prec["*"] = 3
    prec["/"] = 3
    prec["+"] = 2
    prec["-"] = 2
    prec["("] = 1

    op_stack = Stack()
    postfix_list = []
    # 一定要有空格切割,显得不完美
    token_list = infix_expr.split()

    for token in token_list:
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            postfix_list.append(token)
        elif token == "(":
            op_stack.push(token)
        elif token == ")":
            top_token = op_stack.pop()
            while top_token != "(":
                postfix_list.append(top_token)
                top_token = op_stack.pop()
        else:
            while (not op_stack.is_empty()) and \
                  (prec[op_stack.peek()] >= prec[token]):
                postfix_list.append(op_stack.pop())
            op_stack.push(token)
    while not op_stack.is_empty():
        postfix_list.append(op_stack.pop())
    print(" ".join(postfix_list))
    return " ".join(postfix_list)

# 计算后缀表达式的值
def postfix_eval(postfix_expr):
    operand_stack = Stack()
    token_list = postfix_expr.split()

    for token in token_list:
        if token in "0123456789":
            operand_stack.push(int(token))
        else:
            operand2 = operand_stack.pop()
            operand1 = operand_stack.pop()
            # 还是将后缀换成中缀再计算
            result = do_math(token, operand1, operand2)
            operand_stack.push(result)
    return operand_stack.pop()

def do_math(op, op1, op2):
    if op == "*":
        return op1 * op2
    elif op == "/":
        return op1 / op2
    elif op == "+":
        return op1 + op2
    elif op == "-":
        return op1 - op2
    else:
        raise("ERROR")

if __name__ == "__main__":
    print(postfix_eval(infix_to_postfix("5 * 8 + 2 * 3")))
    infix_to_postfix("( A + B ) * C - ( D - E ) * ( F + G )")
    print(postfix_eval('7 8 + 3 2 + /'))

 输出:

>>>
5 8 * 2 3 * +
46
A B + C * D E - F G + * -
3
>>>

  

时间: 2024-10-31 16:43:32

利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现的相关文章

数据结构Java实现06----中缀表达式转换为后缀表达式

本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *.又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符) 前缀表达式:同后缀表达式一样,不包含括号,运算符放在两个

[导入]中缀表达式转换为后缀表达式(C)

中缀表达式向后缀表达式转换文章来源:http://blog.csdn.net/chsword/archive/2007/03/02/1518999.aspx

java数据结构与算法之中缀表达式转为后缀表达式的方法_java

本文实例讲述了java数据结构与算法之中缀表达式转为后缀表达式的方法.分享给大家供大家参考,具体如下: //stack public class StackX { private int top; private char[] stackArray; private int maxSize; //constructor public StackX(int maxSize){ this.maxSize = maxSize; this.top = -1; stackArray = new char[

php四则运算:中缀表达式转后缀表达式例子

四则运算表达式,我们书面使用的叫做中缀表达式,而计算器,却更加喜欢后缀表达,括号优先级,加减乘除优先级等使得运算中缀四则表达式变得困难.这个时候引入了一种计算机喜欢的格式,叫做后缀表达式.本文以PHP代码,实现中缀表达式转后缀表达式的逻辑.     本文以PHP为代码环境,有人会说高级语言直接写表达式就好了,它们会算,可是他们为什么会算,怎么算的,还是需要把中缀表达式转为后缀表达式.因此本文代码只是模拟一个逻辑.     比如:传统的四则运算表达式(中缀表达式)是9 + ( 3 - 1 ) *

详解C++编程中的主表达式与后缀表达式编写基础_C 语言

主表达式主表达式是更复杂的表达式的构造块.它们是文本.名称以及范围解析运算符 (::) 限定的名称.主表达式可以具有以下任一形式: literal this :: name name ( expression ) literal 是常量主表达式.其类型取决于其规范的形式. this 关键字是指向类对象的指针.它在非静态成员函数中可用,并指向为其调用函数的类的实例. this 关键字只能在类成员函数体的外部使用. this 指针的类型是未特别修改 this 指针的函数中的 type *const(

【算法与数据结构】中缀表达式转为后缀表达式

(转载请注明出处:http://blog.csdn.net/buptgshengod) 1.题目介绍     中缀表达式是将运算符放在运算数中间的写法,如a+b*c.后缀表达式是将运算符放在运算数后面,如abc*+. 2.代码实现部分 import java.util.Stack; public class Main { private String testString = null; private Stack<Character> stack = null; public Main(St

经典白话算法之中缀表达式和后缀表达式

一.后缀表达式求值 后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储. 假定待求值的后缀表达式为:6  5  2  3  + 8 * + 3  +  *,则其求值过程如下: (1)遍历表达式,遇到的数字首先放入栈中,依次读入6 5 2 3 此时栈如下所示: (2)接着读到"+",则从栈中弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中. (3)然后读到8(数字入栈),将其直接放入栈中. (4)读到"*",弹出8和5,执行8*5,并将结果40压入栈中

中缀转后缀表达式并求值

通过栈将中缀表达式转换为后缀表达式并根据后缀表达式求解,包含的Header.h为之前发过的栈操作相关函数实例程序,改成头文件就行.练习+记录,高手无视. OutPut: The init formula:3+4*5+(6*7+8)*9 The stack is empty. Convert result:345*+67*8+9*+ Calculate result:473 //Code by Pnig0s1992 //Date:2012,3,21 #include <stdio.h> #inc

前缀中缀后缀表达式

它们都是对表达式的记法,它们之间的区别在于运算符相对于操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前:中缀和后缀同理. 将中缀表达式转换为前缀表达式 (1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2: (2) 从右至左扫描中缀表达式: (3) 遇到操作数时,将其压入S2: (4) 遇到运算符时,比较其与S1栈顶运算符的优先级: (4-1) 如果S1为空,或栈顶运算符为右括号")",则直接将此运算符入栈: (4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算