How many of lines of code for infix-to-prefix?
blog.emmettshear.com
blog.emmettshear.com
def parse(s):
for operator in ["+-", "*/"]:
depth = 0
for p in xrange(len(s) - 1, -1, -1):
if s[p] == ')': depth += 1
if s[p] == '(': depth -= 1
if not depth and s[p] in operator:
return [s[p]] + parse(s[:p]) + parse(s[p+1:])
s = s.strip()
if s[0] == '(':
return parse(s[1:-1])
return [s]
print parse("1+3* 4/haha-5*(2+3.14 ) * (4+5)")
Edit: grammerI think you need one more edit. :-)
It also handles function calls; sin(x) becomes (sin x). For example:
* (infix-to-prefix '(1 + sin(3 + x) * 42))
(+ 1 (* (SIN (+ 3 X)) 42))
If you want the input to be a string, just use read-from-string and add parens at each end of the input string. def in_to_pre_fix(expr, opers=%w(*/ +-))
subex = "\\s*(?:(?:<([^>]+)>)|([\\w]+))\\s*"
while expr !~ /^<[^>]*>$/ and expr.sub!(/(?:^|\()([^)(]*)(?:\)|$)/) { | m |
opers.each { | oper |
while m.sub!(Regexp.new("#{subex}([#{Regexp.quote(oper)}])#{subex}"),
'<\3 \1\2 \4\5>'); end }
m.tr_s("() "," ").strip() }; end
expr.delete("<>")
end
(I'm new to Ruby, so it may not be idiomatic or preferred whitespace-style.) def doit(expr):
expr=''.join(expr.split())
if expr.startswith('('):
(left,size) = doit(expr[1:])
size+=2
else:
left = re.compile('(\w+)').match(expr).groups(0)[0]
size = len(left)
rest = expr[size:]
if rest=='' or rest[0]==')':
return left,size
op = re.compile('([*/+-])').match(rest).groups(0)[0]
right,size2 = doit(rest[1:])
return '(%s %s %s)'%(op, left, right) ,size+size2+1 print parse_expr("1+2/3/4-5*6")
Result: (+ 1 (/ 2 (/ 3 (- 4 (* 5 6)))))