What is the most efficient algorithm to evaluate a RPN notation in R?
Here is the question: suppose we have
c("4", "13", "5", "/", "+") -> (4 + (13 / 5)) -> 6
How to write a general purpose function that evaluates any input RPN ?
Does R have stack data structure ?
Thanks for your hints
The method is follows, evaluating the expression from left to right: When you encounter an operand, push it onto the stack. When you encounter an operator, pop two values from the stack and push the result back onto the stack. When you have finished (been through the whole expression), pop the final answer from the ...
Stacks can be used to evaluate postfix notation equations (also known as Reverse Polish notation ). So the algorithm moves along the expression, pushing each operand on the stack while operators cause two items to be popped off the stack , evaluated and the result pushed back on the stacks .
What Does Reverse Polish Notation (RPN) Mean? Reverse Polish notation (RPN) is a method for conveying mathematical expressions without the use of separators such as brackets and parentheses. In this notation, the operators follow their operands, hence removing the need for brackets to define evaluation priority.
Reverse Polish notation (RPN) is a method for representing expressions in which the operator symbol is placed after the arguments being operated on. Polish notation, in which the operator comes before the operands, was invented in the 1920s by the Polish mathematician Jan Lucasiewicz.
To my knowledge there isn't a dedicated stack structure that you can push/pop etc., but you can easily use lists to achieve the same effect. Here we use the same list to hold the input RPN string and to act as the stack:
rpn <- function(v) {
l <- lapply(v, function(x) if(grepl("^\\d+$", x)) as.numeric(x) else as.name(x))
i <- 1
while(length(l) >= i) {
if(!is.numeric(l[[i]])) {
l[[i - 2]] <- as.call(l[c(i, i - 2, i - 1)])
l[i:(i - 1)] <- NULL
i <- i - 1
} else i <- i + 1
}
l[[1]]
}
Let's test:
v <- c("4", "13", "5", "/", "+")
rpn(v) # un-evaluated reparsed expression
# 4 + 13/5
eval(rpn(v)) # which you can evaluate
# [1] 6.6
Something more challenging:
v <- c("4", "13", "+", "5", "/", "8", "-", "10", "3", "+", "*")
rpn(v)
# ((4 + 13)/5 - 8) * (10 + 3)
eval(rpn(v))
# [1] -59.8
A breakdown of the logic:
That's it. We take advantage that R stores calls as nested lists and that +
, -
, etc. are just functions in R so this works very naturally.
Assumptions:
-
or +
, among other things)c("3", "+", "3")
) will fail.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With