How to Create a Reverse Polish Notation Calculator in Javascript

  • Home /
  • Blog Posts /
  • How to Create a Reverse Polish Notation Calculator in Javascript

The challenge

Your job is to create a calculator which evaluates expressions in Reverse Polish notation.

For example expression 5 1 2 + 4 * + 3 - (which is equivalent to 5 + ((1 + 2) * 4) - 3 in normal notation) should evaluate to 14.

For your convenience, the input is formatted such that a space is provided between every token.

The empty expression should evaluate to ``.

Valid operations are +-*/.

You may assume that there won’t be exceptional situations (like stack underflow or division by zero).

The solution in Javascript

Option 1:

function calc(expr) {  
  var result = [];
  var atoms = expr.split(/\s+/);
  var operators = ['+', '-', '*', '/'];
  for (var i=0; i<atoms.length; i++) {
    switch(atoms[i]) {
      case '+': result.push(result.pop() + result.pop()); break;
      case '-': result.push(-result.pop() + result.pop()); break;
      case '*': result.push(result.pop() * result.pop()); break;
      case '/': result.push(1 /(result.pop() / result.pop())); break;
      default: result.push(parseFloat(atoms[i]));
    }
  }
  return result.pop() || 0;
}

Option 2:

function calc(expr) {
  var stack = [];
  expr.split(" ").forEach(function(e) {
    if (e === "+") stack.push(stack.pop() + stack.pop());
    else if (e === "-") stack.push(-stack.pop() + stack.pop());
    else if (e === "*") stack.push(stack.pop() * stack.pop());
    else if (e === "/") stack.push(1 / stack.pop() * stack.pop());
    else stack.push(parseFloat(e));
  });
  return stack[stack.length - 1] || 0;
}

Option 3:

function calc(s) {
  var r=/(-?[\d\.]+) (-?[\d\.]+) ([-+\*\/])/
  while(s!=""&&r.test(s)) s=s.replace(r,(_,a,b,op)=>eval(a+op+b))
  return +s.match(/-?[\d\.]+$/)
}

Test cases to validate our solution

describe("Tests", () => {
  it("test", () => {
    Test.assertEquals(calc(""), 0, "Should work with empty string");
    Test.assertEquals(calc("3"), 3, "Should parse numbers");
    Test.assertEquals(calc("3.5"), 3.5, "Should parse float numbers");
    Test.assertEquals(calc("1 3 +"), 4, "Should support addition");
    Test.assertEquals(calc("1 3 *"), 3, "Should support multiplication");
    Test.assertEquals(calc("1 3 -"), -2, "Should support subtraction");
    Test.assertEquals(calc("4 2 /"), 2, "Should support division");
  });
});