Hone logo
Hone
Problems

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 integer value to the top of the stack.
  • pop(): Removes and returns the top element from the stack. If the stack is empty, it should return None.
  • peek(): Returns a reference to the top element of the stack without removing it. If the stack is empty, it should return None.
  • is_empty(): Returns true if the stack is empty, false otherwise.
  • 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 push operation should have a time complexity of O(1).
  • The pop, peek, is_empty, and size operations 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 when pop or peek is called.
  • Pay close attention to Rust's ownership and borrowing rules when implementing the peek function. 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. The Vec's len() method is your friend.
  • Focus on clarity and readability in your code. Use meaningful variable names and comments where necessary.
Loading editor...
rust