Reputation:
I am having trouble coming up with a recursive method that can solve fully parenthesized equations..such as ((3+2)/(1+4))
. I was able to come up with a recursive solution for solving infix expressions like +*+3421
using recursion, but for something like ((3+2)/(1+4))
I am a little stuck.
def evalPrefix(exp):
it = iter(exp)
return evalPrefixInner(it)
def evalPrefixInner(it):
item = it.next()
if isInt(item):
return int(item)
else:
operand1 = evalPrefixInner(it)
operand2 = evalPrefixInner(it)
return execute(item, operand1, operand2)
Upvotes: 4
Views: 1218
Reputation: 250961
Try the shunting-yard algorithm
:
dic={"+": lambda x, y:x+y,
"-": lambda x, y:x-y,
"/": lambda x, y:x/y,
"%": lambda x, y:x%y,
"*": lambda x, y:x*y}
def algo(x, op=None, nums=None):
if x != "":
op = op if op else []
nums = nums if nums else []
item = x[0]
if item in ("+","-","%","/","*"):
op.append(item)
if item.isdigit():
nums.append(item)
if item==")":
operator = op.pop()
opd1, opd2 = int(nums.pop()), int(nums.pop())
ans = dic[operator](opd1, opd2)
nums.append(ans)
return algo(x[1:], op, nums)
else:
if op and nums:
operator = op.pop()
opd1, opd2 = int(nums.pop()), int(nums.pop())
return dic[operator](opd1, opd2)
else:
return nums[-1]
print algo("((3+2)/(1+4))") #output :1
print algo("((5+2)*3*(2+5))") #output :147
Upvotes: 2
Reputation: 5953
Your grammar is:
expr ::= int | ( expr op expr )
correct?
So, ignoring error checking, something like...
def evalExpr(it):
item = it.next()
if isInt(item):
return int(item)
else:
//item should = lparen
operand1 = evalExpr(it)
op = it.next()
operand2 = evalExpr(it)
rparen = it.next()
return execute(op, operand1, operand2)
Upvotes: 2
Reputation: 1062
Parse the input for valid data and then use the compiler
module to parse the expression like so:
import compiler
expr = compiler.compile(r'((3+2)/(4+1))', 'err', 'eval')
and then you can use:
eval(expr)
Upvotes: 0