#!/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))