
逆波兰表达式(Reverse Polish Notation)转换:
逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法),是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。因此逆波兰记法广泛地被用于计算器。
SPOJ的ONP问题正是逆波兰表达式的生成问题.
这个问题可以用火车调度场算法解决,Shunting yard算法是一个用于将中缀表达式转换为后缀表达式的经典算法,由艾兹格·迪杰斯特拉引入,因其操作类似于火车编组场而得名。非常巧妙.具体可参考这里.
下面是AC的代码,py2.7
import string
def rpnGenerate(s):
pri = {'+':0,'-':0,'*':1,'/':1,'^':2,'!':3}
pat = {'+':'left','-':'left','*':'left','/':'left','^':'right','!':'right'}
rpn = '' # result rpn string
stack = [] # operator stack
for c in s:
if c==' ':
continue
## # output the current char, rpn and op stack
## print '%s %10s %10s' % (c,rpn,stack)
if c in string.digits+string.ascii_letters: # num
rpn += c
elif c=='(': # (
stack.insert(0,c)
elif c==')': # )
if '(' not in stack: # error, no ( in stack
break
n = stack.pop(0) # pop operator until ( is the stack top
while n!='(':
rpn += n
n = stack.pop(0)
else: # operators
if len(stack)==0:
stack = [c]
continue
# pop a op if:
# 1. stack top is not ( or )
# 2. current op is left combine and priority is small than or equal to op on stack top
# 3. current op is right combine and priority is small than op on stack top
elif (stack[0] not in '()') and ((pat[c]=='left' and pri[c]<=pri[stack[0]]) or (pat[c]=='right' and pri[c]<pri[stack[0]])):
rpn += stack.pop(0)
# push op in stack
stack.insert(0,c)
if len(stack)>0: # stack is not empty
if stack[0] in '()': # has ( or ), quotations don't match
return 'error'
else: # pop up all ops and return rpn
rpn += ''.join(stack)
return rpn
else: # empty stack, return rpn
return rpn
n = int(raw_input())
i = 0
while i<n:
s = raw_input()
print rpnGenerate(s)
i += 1
No comments :
Post a Comment