#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from sys import argv
from decimal import *
def delBlank(str):
"""
Delete all blanks in the str
"""
ans = ""
for e in str:
#print(e)
if e != " ":
ans += e
#print(ans)
return ans
def getPriority(c):
"""
操作符中:"+、-优先级低,*、/、%优先级高" ,^待续
"""
if (c=='+' or c=='-'):
return 0
elif(c == '*' or c == '/' or c == '%'):
return 1
elif (c=='^'):
return 2
def infix2postfix(str):
"""
把中缀表达式转化为后缀表达式:
1、当读到一个操作数时,立即将它放到输出中,读到的是操作符则需要接着判断是否入栈。读到的是左括号则入栈。
2、如果遇到一个右括号,那么就将栈中元素弹出并输出直到遇到左括号为止。但是这个左括号只被弹出,不被输出。
3、在读到操作符时,如果此操作符优先级小于或等于栈顶操作符,则将栈中元素弹出直至(1)遇到左括号(2)栈顶元素为更低优先级
(3)栈为空。操作数中'+','-'优先级最低,
4、如果读到输入的末尾,将栈元素弹出之道该栈变为空栈,将弹出的符号写到输出中。
"""
postfix = []
stackOfOperator = []
index,pos,length = -1,0,len(str)
while(index < length-1):#python for index in range(length):不行,不馆循环内是否更改index,index都是会从1到length-1。
index +=1
char = str[index]
if(char in "0123456789"):#如果是数字,直接输出
pos = index
while(index <length and str[index] in "0123456789"):
index +=1
postfix.append(str[pos:index])
index -= 1
continue
elif(char == ')'):#)右括号,将栈中元素弹出只至左括号,且左括号和右括号不加入到后缀表达式
while(True):
tmp = stackOfOperator.pop()
if(tmp=="("):
break
postfix.append(tmp)
elif(char == "("):#左括号直接压入栈中
stackOfOperator.append(char)
else:
if len(stackOfOperator) == 0:#如果栈为空,则直接压入
stackOfOperator.append(char)
continue
top = stackOfOperator[-1]
if (top == '('):#操作符栈顶为左括号(,则将当前操作符入栈。
stackOfOperator.append(char)
continue
if(getPriority(char)<=getPriority(top)):
#如果此操作符(+,-,*,/,%)的优先级小于或等于栈顶的元素
#则将栈中元素弹出至(1)遇到左括号(2)栈顶元素为更低优先级(3)栈为空为止
#并将弹出的元素加入后缀表达式中,将单曲操作数压入栈中
while(True):
tmp = stackOfOperator[-1]
if(tmp == '(' or getPriority(tmp) < getPriority(char)):
break
postfix.append(tmp)
stackOfOperator.pop()
if len(stackOfOperator)==0:
break
stackOfOperator.append(char)
else:
#如果当前操作符优先级大于此时当前栈顶操作数,则讲当前操作数压入栈
stackOfOperator.append(char)
while(len(stackOfOperator)):
postfix.append(stackOfOperator.pop())
return postfix
def operate(num1,num2,operator):
if operator == "+":
return num1 + num2
elif operator == "-":
return num1 - num2
elif operator == "*":
return num1 * num2
elif operator == "/":
return num1 / num2
elif operator == "%":
return num1 % num2
elif operator == "^":
return num1 ** num2
'''
通过后缀表达式计算数值
1、从左到有遍历表达式的每个数字和符号,若是遇到数字则进栈,遇到运算符则将栈顶两个元素出栈,进行运算并将运算结果进栈
2、遍历完后缀表达式,此时栈中剩余的数字就是运算结果
'''
def calculateByPostfix(postifix):
stackOfNumber =[]
index,length = 0,len(postifix)
while index < length:
e = postifix[index]
if e in "+-*/%^":#后进先出
num2 = float(stackOfNumber.pop())
num1 = float(stackOfNumber.pop())
stackOfNumber.append(operate(num1,num2,e))
print(stackOfNumber)
else:
stackOfNumber.append(e)
print(stackOfNumber)
index += 1
return stackOfNumber
if __name__ == '__main__':
#get the exp
exp = ""
for i in range(len(argv)-1):
exp += argv[i+1]
print(exp)
exp = delBlank(exp)
print(exp)
postfix=infix2postfix(exp)
print(postfix)
print(calculateByPostfix(postfix))
转载于:https://www.cnblogs.com/zangkuo/p/6115218.html