计算后缀表达式

参考链接:

 https://www.cnblogs.com/hantalk/p/8734511.html

https://www.cnblogs.com/bhep/p/7763647.html

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

"""
File: tokens.py
Tokens for processing expressions
"""


class Token(object):
	UNKNOWN = 0  # unknown
	INT = 4  # integer
	BRANKET = 3
	MINUS = 5  #
	PLUS = 6
	MUL = 7
	DIV = 8
	SQR = 9
	FIRST_OP = 5  # first operator code

	FIRST = 1
	SECOND = 2
	THIRD = 3

	def __init__(self, value):
		if value.isdigit():
			self._type = Token.INT
		else:
			self._type = self._maketype(value)
		self._value = value

	def isOperator(self):
		return self._type >= Token.FIRST_OP

	def __str__(self):
		return str(self._value)

	def getType(self):
		return self._type

	def getValue(self):
		return self._value

	def _maketype(self, ch):
		if ch == "*":
			return Token.MUL
		elif ch == "/":
			return Token.DIV
		elif ch == "+":
			return Token.PLUS
		elif ch == "-":
			return Token.MINUS
		elif ch == "^":
			return Token.SQR
		elif ch == "(":
			return Token.BRANKET
		else:
			return Token.UNKNOWN

	def getPrecedence(self):
		if self._value == "+" or self._value == "-":
			return Token.FIRST
		elif self._value == "/" or self._value == "*":
			return Token.SECOND
		elif self._value == "(":
			return Token.THIRD


 scanner.py

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

'''
@author: liudaoqiang
@file: studycase
@time: 2018/9/4 20:52
'''

from arraystack import ArrayStack
from tokens import Token

class Scanner(object):

	def __init__(self, sourceStr):
		token = list()
		for item in list(sourceStr):
			token.append(Token(item))
			print(Token(item).getType())
		self._sourceStr = ArrayStack(token)
		# print(self._sourceStr)

	def next(self):
		return self._sourceStr.pop()

	def hasNext(self):
		return self._sourceStr.isEmpty()

models.py 

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

from arraystack import ArrayStack
from tokens import Token
from scanner import Scanner
from iftopfconverter import IFToPFConverter

class PFEvaluator(object):

	def __init__(self, scanner):
		self._expressSoFar = ""
		self._operandStack = ArrayStack()
		self._scanner = scanner

	def evaluate(self):
		while not self._scanner.hasNext():
			currentToken = self._scanner.next()
			self._expressSoFar += str(currentToken) + " "
			# 计算加法
			if currentToken.getType() == Token.INT:
				self._operandStack.push(currentToken)
			elif currentToken.isOperator():
				if len(self._operandStack) == 0:
					raise KeyError("Too few operands on the stack")
				t2 = self._operandStack.pop()
				t1 = self._operandStack.pop()
				result = Token(self._computeValue(currentToken,
													t1.getValue(),
													t2.getValue()))
				self._operandStack.push(result)
			else:
				raise KeyError("Unknown token type")

		if len(self._operandStack) > 1:
			raise AttributeError("Two many operands on the stack")
		result = self._operandStack.pop()
		return result.getValue()

	def __str__(self):
		result = "\n"
		if self._expressSoFar == "":
			result += "Portion of expression processed: none\n"
		else:
			result += "Portion of expression processed: " +\
				self._expressSoFar + "\n"
		if self._operandStack.isEmpty():
			result += "The stack isEmpty"
		else:
			result += "Operands on the stack:" +\
				str(self._operandStack)
		return result

	def _computeValue(self, op, value1, value2):
		result = 0
		value2 = int(value2)
		value1 = int(value1)
		theType = op.getType()
		if theType == Token.PLUS:
			result = value1 + value2
		elif theType == Token.MINUS:
			result = value1 - value2
		elif theType == Token.MUL:
			result = value1 * value2
		elif theType == Token.DIV:
			result = value1 / value2
		elif theType == Token.SQR:
			result = value1 ** value2
		else:
			raise AttributeError("Unknown operator")
		return str(result)


class PFEvaluatorModel(object):

	def evaluate(self, sourceStr):
		self._evaluator = PFEvaluator(Scanner(sourceStr))
		value = self._evaluator.evaluate()
		return value

	def __format__(self, sourceStr):
		normalizedStr = ""
		scanner = Scanner(sourceStr)
		while scanner.hasnext():
			normalizedStr += str(scanner.next())
		return normalizedStr

	def evaluationStatus(self):
		return str(self._evaluator)

if __name__ == "__main__":
	"""
	{^, 3, +, 2, 1, None, None, None, None, None}
	27
	===========================
	{), 3, -, 6, (, *, ), 5, +, 4, (, None}
	['4', '5', '+', '6', '3', '-', '*']
	===========================
	45+63-*
	{*, -, 3, 6, +, 5, 4, None, None, None}
	27
	"""
	print("计算后缀表达式")
	sourceStr = "12+3^"
	scanner = Scanner(sourceStr)
	print(scanner._sourceStr)
	pfEvaluator = PFEvaluator(scanner)
	# print(pfEvaluator)
	print(pfEvaluator.evaluate())

	print("===========================")
	print("先中缀表达式转换成后缀表达式")
	sourceStr = "(4+5)*(6-3)"
	scanner = Scanner(sourceStr)
	print(scanner._sourceStr)
	iftoPFConverter = IFToPFConverter(scanner)
	iftoPFConverter.convert()
	print(iftoPFConverter._postExPression)
	print("===========================")
	print("计算后缀表达式")
	sourceStr = ''.join(iftoPFConverter._postExPression)
	print(sourceStr)
	scanner = Scanner(sourceStr)
	print(scanner._sourceStr)
	pfEvaluator = PFEvaluator(scanner)
	print(pfEvaluator)
	print(pfEvaluator.evaluate())

iftopfconverter.py

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

'''
@author: liudaoqiang
@file: studycase
@time: 2018/9/5 18:17
'''

from scanner import Scanner
from tokens import Token
from arraystack import ArrayStack


class IFToPFConverter(object):

	def __init__(self, scanner):
		self._scanner = scanner
		self._arraystack = ArrayStack()
		self._postExPression = list()

	def convert(self):
		scannerStack = self._scanner
		while not scannerStack.hasNext():
			item = scannerStack.next()
			if self._arraystack.isEmpty():
				"""如果栈为空就,就直接压入栈中"""
				self._arraystack.push(item)
			else:
				if item.getValue() == "(":
					"""左括号压入栈中"""
					self._arraystack.push(item)
				elif item.getValue() == ")":
					"""遇到后括号时,从栈中弹出所有的符号,并且将对应的左括号删除"""
					while not self._arraystack.isEmpty() and self._arraystack.peek().getValue() != "(":
						self._postExPression.append(self._arraystack.pop().getValue())
					if not self._arraystack.isEmpty() and self._arraystack.peek().getValue() == "(":
						self._arraystack.pop()
				elif item.getType() >= Token.FIRST_OP:
					# print(item.getValue())
					# print(self._arraystack.peek())
					"""给压入栈中的所有符号都分配了优先级,因此要特别考虑左括号
						当非括号栈顶优先级不小于item的优先级,将栈顶弹出加入表达式,并把item压入栈
					"""
					while self._arraystack.peek().getPrecedence() >= item.getPrecedence() and self._arraystack.peek().getValue() != "(":
						self._postExPression.append(self._arraystack.pop().getValue())
					self._arraystack.push(item)
				elif item.getValue().isdigit():
					"""数组直接加入到表达式中"""
					self._postExPression.append(item.getValue())
				else:
					"""输入非法字符"""
					raise AttributeError("not operand or operandor")

		while not self._arraystack.isEmpty():
			"""将栈中剩余字符都加入的表达式中"""
			self._postExPression.append(self._arraystack.pop().getValue())
		return self._postExPression

	def __str__(self):
		return str(self._postExPression)


if __name__ == "__main__":
	"""
	{), 3, -, 6, (, *, ), 5, +, 4, (, None}
	['4', '5', '+', '6', '3', '-', '*']

	"""
	sourceStr = "(4+5)*(6-3)"
	# sourceStr = sourceStr[::-1]
	scanner = Scanner(sourceStr)
	print(scanner._sourceStr)
	iftoPFConverter = IFToPFConverter(scanner)
	print(iftoPFConverter.convert())

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值