Skip to content

Commit 52858f8

Browse files
feat: add algorithm to evaluate postfix string (#1441)
* feat: add algorithm to evaluate postfix strings * feat: add test case for evaluate expression * update: add literature reference * fix: import name in testcase * fix: test case result * Make clear that this is postfix * Update tests * add: see reference * fixes mentioned issues * Fix `default` case --------- Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
1 parent 05750bc commit 52858f8

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Evaluate a numeric operations string in postfix notation using a stack.
3+
* Supports basic arithmetic operations: +, -, *, /
4+
* @see https://www.geeksforgeeks.org/evaluation-of-postfix-expression/
5+
* @param {string} expression - Numeric operations expression to evaluate. Must be a valid postfix expression.
6+
* @returns {number|null} - Result of the expression evaluation, or null if the expression is invalid.
7+
*/
8+
function evaluatePostfixExpression(expression) {
9+
const stack = [];
10+
11+
// Helper function to perform an operation and push the result to the stack. Returns success.
12+
function performOperation(operator) {
13+
const rightOp = stack.pop(); // Right operand is the top of the stack
14+
const leftOp = stack.pop(); // Left operand is the next item on the stack
15+
16+
if (leftOp === undefined || rightOp === undefined) {
17+
return false; // Invalid expression
18+
}
19+
switch (operator) {
20+
case '+':
21+
stack.push(leftOp + rightOp);
22+
break;
23+
case '-':
24+
stack.push(leftOp - rightOp);
25+
break;
26+
case '*':
27+
stack.push(leftOp * rightOp);
28+
break;
29+
case '/':
30+
if (rightOp === 0) {
31+
return false;
32+
}
33+
stack.push(leftOp / rightOp);
34+
break;
35+
default:
36+
return false; // Unknown operator
37+
}
38+
return true;
39+
}
40+
41+
const tokens = expression.split(/\s+/);
42+
43+
for (const token of tokens) {
44+
if (!isNaN(parseFloat(token))) {
45+
// If the token is a number, push it to the stack
46+
stack.push(parseFloat(token));
47+
} else {
48+
// If the token is an operator, perform the operation
49+
if (!performOperation(token)) {
50+
return null; // Invalid expression
51+
}
52+
}
53+
}
54+
55+
return (stack.length === 1) ? stack[0] : null;
56+
}
57+
58+
export { evaluatePostfixExpression };
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { evaluatePostfixExpression } from '../EvaluateExpression.js';
2+
3+
describe('evaluatePostfixExpression', () => {
4+
it('should evaluate a valid expression', () => {
5+
const expression = '3 4 * 2 / 5 +'; // (3 * 4) / 2 + 5 = 11
6+
const result = evaluatePostfixExpression(expression);
7+
expect(result).toBe(11);
8+
});
9+
10+
it('should handle division by zero', () => {
11+
const expression = '3 0 /'; // Division by zero
12+
const result = evaluatePostfixExpression(expression);
13+
expect(result).toBe(null);
14+
});
15+
16+
it('should handle an invalid expression', () => {
17+
const expression = '3 * 4 2 / +'; // Invalid expression
18+
const result = evaluatePostfixExpression(expression);
19+
expect(result).toBe(null);
20+
});
21+
22+
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy