📖 Scenario: You are building a simple stack data structure that can grow dynamically as you add more items. Imagine a stack of plates that can get taller when you add more plates.
🎯 Goal: Create a dynamic stack using a resizable array (Rust Vec) that supports pushing and popping elements.
📋 What You'll Learn
Create a stack using a Vec<i32> named stack with initial elements
Add a variable capacity to track the current capacity of the stack
Write code to push a new element onto the stack and increase capacity if needed
Write code to pop the top element from the stack
Print the final state of the stack after operations
💡 Why This Matters
🌍 Real World
Dynamic stacks are used in many applications like undo features in text editors, expression evaluation, and backtracking algorithms.
💼 Career
Understanding dynamic data structures like stacks is essential for software development roles involving algorithms, system design, and performance optimization.
Progress0 / 4 steps
1
Create the initial stack
Create a Vec<i32> called stack with these exact elements: 10, 20, 30
DSA Rust
Hint
Use vec![10, 20, 30] to create the vector and name it stack.
2
Add capacity variable
Add a variable called capacity and set it to the current capacity of stack using stack.capacity()
DSA Rust
Hint
Use stack.capacity() to get the current capacity and store it in capacity.
3
Push and pop elements
Push the element 40 onto stack. If the length of stack is now greater than capacity, update capacity to the new stack.capacity(). Then pop the top element from stack and store it in a variable called popped.
DSA Rust
Hint
Use stack.push(40) to add, check length with stack.len(), update capacity if needed, then use stack.pop() to remove the top element.
4
Print the final stack
Print the final state of stack using println!("{:?}", stack)
DSA Rust
Hint
Use println!("{:?}", stack) to print the vector in debug format.
Practice
(1/5)
1. What is the main advantage of using a dynamic stack implemented with a resizable array compared to a fixed-size array stack?
easy
A. It does not require resizing or copying elements.
B. It can grow or shrink in size as needed during runtime.
C. It always has a fixed maximum size.
D. It uses less memory than a linked list stack.
Solution
Step 1: Understand fixed vs dynamic size
A fixed-size array stack has a set capacity that cannot change during runtime, limiting the number of elements it can hold.
Step 2: Analyze dynamic stack behavior
A dynamic stack using a resizable array can increase or decrease its capacity by resizing the underlying array, allowing it to handle more or fewer elements as needed.
Final Answer:
It can grow or shrink in size as needed during runtime. -> Option B
Quick Check:
Dynamic resizing = flexible size [OK]
Hint: Dynamic stack resizes array to fit elements [OK]
Common Mistakes:
Thinking dynamic stack has fixed size
Confusing linked list with array stack
Assuming no resizing needed
2. Which Rust code snippet correctly doubles the capacity of a vector when the stack is full?
easy
A. if stack.len() == stack.capacity() { stack.reserve(stack.capacity()); }
B. if stack.len() == stack.capacity() { stack.reserve(1); }
C. if stack.len() == stack.capacity() { stack.reserve(stack.len() / 2); }
D. if stack.len() == stack.capacity() { stack.reserve(0); }
Solution
Step 1: Understand vector capacity and reserve method
The vector's capacity is the total space allocated. To double capacity, we add capacity() more space using reserve(capacity()).
Step 2: Check each option's reserve argument
if stack.len() == stack.capacity() { stack.reserve(stack.capacity()); } reserves current capacity again, doubling it. Others reserve too little or zero, not doubling.
Final Answer:
if stack.len() == stack.capacity() { stack.reserve(stack.capacity()); } -> Option A
Quick Check:
Reserve current capacity to double [OK]
Hint: Reserve current capacity to double vector size [OK]
Common Mistakes:
Reserving fixed small number instead of doubling
Using zero in reserve causing no growth
Confusing len() with capacity()
3. What will be the output of the following Rust code implementing a dynamic stack?
A. reserve argument should be capacity(), not len()
B. reserve should be called after push, not before
C. No bug; code works correctly
D. push should be called only if capacity is not full
Solution
Step 1: Check the resizing logic
When self.data.len() == self.data.capacity(), the stack is full. reserve(self.data.len()) requests additional space for len() more elements. Since len() == capacity() at this point, it doubles the capacity.
Step 2: Verify correctness
reserve(self.data.capacity()) would be equivalent here. The code safely resizes before push, preventing issues, and works correctly. (Rust Vec::push auto-resizes too, but manual is valid.)
Final Answer:
No bug; code works correctly -> Option C
Quick Check:
len() == capacity() when called, so doubles [OK]
Hint: When full, reserve(len()) == reserve(capacity()), doubles size [OK]
Common Mistakes:
Reserving too little space (e.g., reserve(1))
Calling reserve after push causing potential panic
Assuming push auto-resizes without manual check
5. You want to implement a dynamic stack in Rust that shrinks its capacity when the number of elements falls below one-quarter of the capacity to save memory. Which approach correctly achieves this behavior?
hard
A. After pop, if len() < capacity() / 4, call data.shrink_to(len())
B. After pop, if len() < capacity() / 2, call data.reserve(len())
C. After pop, if len() < capacity() / 4, call data.reserve(capacity() / 2)
D. After pop, if len() < capacity() / 4, do nothing; shrinking is automatic
Solution
Step 1: Understand shrinking condition
We want to shrink when elements are less than 25% of capacity to save memory.
Step 2: Use shrink_to method correctly
Calling shrink_to(len()) reduces capacity to fit current elements, freeing unused space.
Step 3: Analyze options
After pop, if len() < capacity() / 4, call data.shrink_to(len()) correctly checks condition and calls shrink_to(len()). Others either use wrong methods or do nothing.
Final Answer:
After pop, if len() < capacity() / 4, call data.shrink_to(len()) -> Option A
Quick Check:
Shrink when quarter full using shrink_to(len()) [OK]
Hint: Shrink vector capacity with shrink_to(len()) when quarter full [OK]
Common Mistakes:
Using reserve instead of shrink_to for shrinking
Shrinking at half capacity instead of quarter
Assuming automatic shrinking without code
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.