Skip to content

Instantly share code, notes, and snippets.

@feixionglee
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save feixionglee/7a96e62a61a78bdd604a to your computer and use it in GitHub Desktop.
Save feixionglee/7a96e62a61a78bdd604a to your computer and use it in GitHub Desktop.
calculate expression
# '( 2 + ( ( 4 + 6 ) * (9 * 2) - ( 5 - 1)))'
class Postfix
include Math
def initialize expression
@expression = expression.gsub(' ', '')
end
def process
postf = transform
print postf
cal postf
end
private
def cal(s)
operand = {nil => 0, '*' => 2, '+' => 2, '-' => 2, '/' => 2, 'sqrt' => 1}
stack = []
size = s.size
for i in 0..size-1 do
if is_digit(s[i])
stack.push s[i]
else
if operand[s[i]] == 2
num2, num1 = stack.pop(2)
a = eval "#{num2} #{s[i]} #{num1}"
elsif operand[s[i]] == 1
num = stack.pop
a = eval "#{s[i]} #{num}"
end
stack.push(a.to_i)
end
end
if stack.count == 1
stack.pop()
else
-1
end
end
def is_digit(ele)
begin
return true if Integer(ele)
rescue
return false
end
end
def transform
precedence = {nil => 0, '' => 0, '(' => 0, '*' => 2, '+' => 1, '-' => 1, '/' => 2, 'sqrt' => 3}
output = Array.new
stack = Array.new
temp = ''
@expression.each_char do |asc|
case asc
when ')'
if temp.length > 0
if is_digit(temp)
output.push(temp)
else
stack.push(temp)
end
temp = ''
end
loop{
if stack.empty? == false
popped = stack.pop
if popped == '('
break
else
output.push(popped)
end
else
raise 'Missing "("!'
end
}
when '(', '+', '-', '*', '/'
if temp.length > 0
if is_digit(temp)
output.push(temp)
else
stack.push(temp)
end
temp = ''
end
unless asc == '('
p_asc = precedence[asc]
loop{
if (p_asc > precedence[stack.last])
break
else
output.push(stack.pop)
end
}
end
stack.push(asc)
else
temp += asc
end
end
stack.each{|asc| output.push(asc)}
!output.include?('(') or raise 'Missing ")"!'
output.delete('')
output
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment