Lesson 2
Problem-solving with Stacks in C++
Introduction to the Lesson

Welcome back! Today, we're exploring stack operations in C++. In this lesson, we will apply the concept of the stack's Last-In, First-Out (LIFO) principle to solve two specific problems that will enhance your understanding of stack operations.

Problem 1: Validating Parentheses

In programming, ensuring the proper nesting and closing of structures like parentheses is crucial. It's akin to making sure each stack of boxes has its correct lid. We'll create a function to confirm that a string of brackets is properly nested and balanced.

Problem 1: Actualization

Misbalanced parentheses can lead to errors, similar to losing a vital piece in a puzzle. Our function acts as a meticulous organizer, ensuring every opening parenthesis is matched by a closing one in the correct order.

Problem 1: Efficient Approach

The stack data structure suits this problem well due to its LIFO nature. It helps track the order of opening and closing brackets, guaranteeing all braces are closed in their proper sequence.

Problem 1: Algorithm

We'll use a std::unordered_map to map each opening bracket to its corresponding closing bracket alongside an empty std::stack. As we iterate through each character in the string, an opening bracket is pushed onto the stack. A closing bracket is checked against the top of the stack to ensure it matches the last opened bracket. If any mismatch or imbalance occurs, the function will return false.

Problem 1: Solution Building

Let's build the solution using C++:

C++
1#include <iostream> 2#include <stack> 3#include <unordered_map> 4#include <set> 5 6bool AreBracketsBalanced(const std::string& inputStr) { 7 std::unordered_map<char, char> bracketMap = { 8 {'(', ')'}, 9 {'[', ']'}, 10 {'{', '}'} 11 }; 12 13 std::set<char> openPar = {'(', '[', '{'}; 14 15 std::stack<char> stack; 16 17 for (char character : inputStr) { 18 if (openPar.find(character) != openPar.end()) { 19 stack.push(character); 20 } else if (!stack.empty() && character == bracketMap[stack.top()]) { 21 stack.pop(); 22 } else { 23 return false; 24 } 25 } 26 27 return stack.empty(); 28} 29 30int main() { 31 std::cout << std::boolalpha << AreBracketsBalanced("(){}[]") << std::endl; // Output: true 32 return 0; 33}

The function returns false in the following cases:

  1. Encountering a closing bracket with an empty stack.
  2. Finding a mismatched closing bracket for the latest opened bracket.
  3. The stack is non-empty after processing, meaning unmatched opening brackets are present.
Problem 2: Reverse a String using a Stack

Now, we'll reverse a string, a simple yet powerful demonstration of data structure utility.

Problem 2: Actualization

Reverse a user-input string or, in advanced applications, reorder network packets using stacks. This shows the stack's ability to alter sequence order efficiently.

Problem 2: Approach Explanation

Using a stack's LIFO feature, we can reverse elements. By pushing characters onto a stack and popping them out, we invert the sequence.

Problem 2: Solution Building

Here's how to implement the solution in C++:

C++
1#include <iostream> 2#include <stack> 3#include <string> 4 5std::string ReverseString(const std::string& str) { 6 std::stack<char> stack; 7 for (char c : str) { 8 stack.push(c); 9 } 10 11 std::string reversed; 12 while (!stack.empty()) { 13 reversed += stack.top(); 14 stack.pop(); 15 } 16 return reversed; 17} 18 19int main() { 20 std::cout << ReverseString("Hello, World!") << std::endl; // Output: !dlroW ,olleH 21 return 0; 22}

This solution clearly exhibits the effectiveness of stack operations. By systematically stacking and unstacking characters, we efficiently construct a reversed string.

Lesson Summary

Today, you've tackled two classic problems using stacks in C++, showcasing their practical utility. The stack's LIFO nature helped verify nested structures' correctness and reverse sequences with efficient and straightforward code. Well done on completing this lesson! The understanding you've gained is vital for solving problems where operation order is crucial. With these skills, you're better equipped for real-world scenarios involving data processing in reverse or verification of correctness.

Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.