Stack Implementation with Push and Pop Operations in Rust
This challenge asks you to implement a basic stack data structure in Rust, focusing on the core push and pop operations. Stacks are fundamental data structures used in various applications, including function call management, expression evaluation, and undo/redo functionality. Successfully completing this challenge will solidify your understanding of Rust's ownership and borrowing system within a practical context.
Problem Description
You are tasked with creating a Stack struct in Rust that supports the following operations:
push(value: i32): Adds a new integervalueto the top of the stack.pop(): Removes and returns the top element from the stack. If the stack is empty, it should returnNone.peek(): Returns a reference to the top element of the stack without removing it. If the stack is empty, it should returnNone.is_empty(): Returnstrueif the stack is empty,falseotherwise.size(): Returns the number of elements currently in the stack.
The stack should be implemented using a Vec<i32> internally. Ensure your implementation handles edge cases gracefully, particularly when attempting to pop or peek from an empty stack.
Examples
Example 1:
Input:
Stack: []
push(1)
push(2)
push(3)
pop()
pop()
peek()
pop()
pop()
is_empty()
size()
Output:
3
2
Some(1)
None
true
0
Explanation: The stack starts empty. We push 1, 2, and 3 onto the stack. Popping removes 3 and then 2. Peeking returns a reference to 1. Popping again removes 1. Finally, the stack is empty, so popping returns None, is_empty() returns true, and size() returns 0.
Example 2:
Input:
Stack: []
pop()
peek()
Output:
None
None
Explanation: Attempting to pop or peek from an empty stack results in None.
Example 3: (Edge Case - Repeated Pops)
Input:
Stack: [1, 2]
pop()
pop()
pop()
Output:
Some(2)
Some(1)
None
Explanation: Demonstrates handling of popping all elements and then attempting to pop from an empty stack.
Constraints
- The stack should store integers (
i32). - The
pushoperation should have a time complexity of O(1). - The
pop,peek,is_empty, andsizeoperations should have a time complexity of O(1). - The stack should be implemented using a
Vec<i32>internally. - The code should compile and run without errors.
Notes
- Consider using Rust's
Option<i32>to handle the case where the stack is empty whenpoporpeekis called. - Pay close attention to Rust's ownership and borrowing rules when implementing the
peekfunction. You'll need to return a reference to the top element without taking ownership. - Think about how to efficiently track the size of the stack without iterating through the entire
Vec. TheVec'slen()method is your friend. - Focus on clarity and readability in your code. Use meaningful variable names and comments where necessary.