Skip to content

Commit e009cd4

Browse files
authored
Create PracticalStacks.js
1 parent 02408aa commit e009cd4

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

03-DataStructures/PracticalStacks.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
1. Function call stack:
3+
In Node.js, a call stack is used to track the order of function calls.
4+
Whenever a function is called, it is pushed onto the stack.
5+
Once the function is done executing, it is popped off the stack.
6+
This ensures that the program knows which function to return to after the current function has finished.
7+
*/
8+
function firstFunction() {
9+
console.log('First function called');
10+
secondFunction();
11+
}
12+
13+
function secondFunction() {
14+
console.log('Second function called');
15+
thirdFunction();
16+
}
17+
18+
function thirdFunction() {
19+
console.log('Third function called');
20+
}
21+
22+
firstFunction();
23+
24+
/*
25+
2. Expression evaluation:
26+
Stacks can be used to evaluate arithmetic expressions in postfix notation (also known as Reverse Polish Notation).
27+
This can be useful when creating a calculator program or when evaluating expressions in a custom language interpreter.
28+
*/
29+
function evaluatePostfixExpression(expression) {
30+
const stack = [];
31+
const operators = {
32+
'+': (a, b) => a + b,
33+
'-': (a, b) => a - b,
34+
'*': (a, b) => a * b,
35+
'/': (a, b) => a / b,
36+
};
37+
38+
expression.split(' ').forEach((token) => {
39+
if (token in operators) {
40+
const b = stack.pop();
41+
const a = stack.pop();
42+
stack.push(operators[token](a, b));
43+
} else {
44+
stack.push(parseFloat(token));
45+
}
46+
});
47+
48+
return stack.pop();
49+
}
50+
51+
console.log(evaluatePostfixExpression('3 4 + 5 *')); // (3 + 4) * 5 = 35
52+
53+
/*
54+
3. Reversing a string:
55+
Stacks can be used to reverse a string by pushing each character onto a stack and then popping them off in reverse order.
56+
*/
57+
function reverseString(str) {
58+
const stack = [];
59+
for (const char of str) {
60+
stack.push(char);
61+
}
62+
63+
let reversed = '';
64+
while (stack.length > 0) {
65+
reversed += stack.pop();
66+
}
67+
68+
return reversed;
69+
}
70+
71+
console.log(reverseString('hello')); // 'olleh'
72+
73+
/*
74+
4. Balancing parentheses:
75+
Stacks can be used to check if a string with parentheses, brackets, and braces is balanced.
76+
This can be useful when validating code or user input.
77+
*/
78+
function isBalanced(input) {
79+
const stack = [];
80+
const pairs = {
81+
'(': ')',
82+
'[': ']',
83+
'{': '}',
84+
};
85+
86+
for (const char of input) {
87+
if (char in pairs) {
88+
stack.push(char);
89+
} else if (Object.values(pairs).includes(char)) {
90+
if (stack.length === 0 || pairs[stack.pop()] !== char) {
91+
return false;
92+
}
93+
}
94+
}
95+
96+
return stack.length === 0;
97+
}
98+
99+
console.log(isBalanced('{[()]}')); // true
100+
console.log(isBalanced('{[(])}')); // false
101+
102+
/*
103+
Undo/Redo functionality:
104+
Stacks can be used to implement undo and redo functionality in an application by keeping track of user actions on two separate stacks.
105+
*/
106+
class History {
107+
constructor() {
108+
this.undoStack = [];
109+
this.redoStack = [];
110+
}
111+
112+
// Add a new action to the undo stack and clear the redo stack
113+
addAction(action) {
114+
this.undoStack.push(action);
115+
this.redoStack = [];
116+
}
117+
118+
// Undo the last action by moving it from the undo stack to the redo stack
119+
undo() {
120+
if (this.undoStack.length === 0) return;
121+
122+
const action = this.undoStack.pop();
123+
this.redoStack.push(action);
124+
console.log(`Undo: ${action}`);
125+
}
126+
127+
// Redo the last undone action by moving it back from the redo stack to the undo stack
128+
redo() {
129+
if (this.redoStack.length === 0) return;
130+
131+
const action = this.redoStack.pop();
132+
this.undoStack.push(action);
133+
console.log(`Redo: ${action}`);
134+
}
135+
}
136+
137+
// Example usage
138+
const history = new History();
139+
140+
history.addAction('Type A');
141+
history.addAction('Type B');
142+
history.addAction('Type C');
143+
144+
history.undo(); // Undo: Type C
145+
history.undo(); // Undo: Type B
146+
147+
history.redo(); // Redo: Type B
148+
history.addAction('Type D'); // Performing a new action resets the redo history
149+
150+
history.redo(); // No action, as redo history has been reset
151+
152+
153+

0 commit comments

Comments
 (0)