"(1+(2*3)+3)". Dijkstra's algorithm uses two stacks: one holds the values and the second one holds the operators. As you are iterating over the string, you push values and operators onto corresponding stack if you encounter an opening parenthesis. Once you encounter a closing parenthesis, you pop a value and an operator, perform an arithmetic operation and push an updated value to the value stack. This implementation requires that the expression has a complete set of opening and closing parentheses.Instead of using Ruby's
Array and corresponding pop() and push() methods, I decided to implement my own stack class as a singly linked list from scratch. By the way, the time complexity for stack operations are as follows: O(1) for push() and pop(). This makes sense since we are just accessing the top element. However, the search for an element would be slow (O(n)), since linked lists do not support indices, and one would have to traverse all the elements to get to the desired one.class Stack
attr_accessor :first
def initialize
@first = Node.new
@len = 0
end
def push(item)
oldfirst = @first
@first = Node.new
@first.item = item
@first.next = oldfirst
@len += 1
end
def peek
return @first.item
end
def pop
item = @first.item
@first = @first.next
@len -= 1
item
end
def empty?
return @len == 0
end
def len
return @len
end
class Node
attr_accessor :item, :next
def initialize
@item = nil
@next = nil
end
end
end
def calculate(str)
values = Stack.new
operators = Stack.new
str.split(" ").each do |i|
if i == '('
# just skip
elsif i == '+'
operators.push(i)
elsif i == '-'
operators.push(i)
elsif i == '*'
operators.push(i)
elsif i == '/'
operators.push(i)
elsif i == 'sqrt'
operators.push(i)
elsif i == ')'
operator = operators.pop
value = values.pop
if operator == '+'
value = values.pop + value
elsif operator == '-'
value = values.pop - value
elsif operator == '*'
value = values.pop * value
elsif operator == '/'
value = values.pop / value
elsif operator == 'sqrt'
value = Math.sqrt(value)
end
values.push(value)
else
values.push(i.to_f)
end
end
values.pop
end
str = "( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )"
puts calculate(str)
str2 = "( ( 1 + sqrt ( 5.0 ) ) / 2.0 )"
puts calculate(str2)
No comments :
Post a Comment