Skip to content

Commit cf23991

Browse files
authored
Fix bugs in Peek() and Pop() to throw an exception when stack is empty (#203)
1 parent cf3ff1e commit cf23991

File tree

2 files changed

+56
-16
lines changed

2 files changed

+56
-16
lines changed

DataStructures.Tests/ArrayBasedStackTests.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
1-
using DataStructures.ArrayBasedStack;
1+
using System;
2+
3+
using DataStructures.ArrayBasedStack;
24

35
using NUnit.Framework;
46

57
namespace DataStructures.Tests
68
{
79
public static class ArrayBasedStackTests
810
{
11+
const string StackEmptyErrorMessage = "Stack is empty";
12+
913
[Test]
1014
public static void CountTest()
1115
{
1216
var stack = new ArrayBasedStack<int>(new[] { 0, 1, 2, 3, 4 });
13-
Assert.IsTrue(stack.Count == 5);
17+
Assert.IsTrue(stack.Top == 4);
1418
}
1519

1620
[Test]
1721
public static void ClearTest()
1822
{
1923
var stack = new ArrayBasedStack<int>(new[] { 0, 1, 2, 3, 4 });
2024
stack.Clear();
21-
Assert.IsTrue(stack.Count == 0);
25+
Assert.IsTrue(stack.Top == -1);
2226
}
2327

2428
[Test]
@@ -80,5 +84,22 @@ public static void AutomaticResizesTest()
8084
stack.Push(4);
8185
Assert.IsTrue(stack.Capacity > 2);
8286
}
87+
88+
[Test]
89+
public static void ShouldThrowStackEmptyExceptionOnEmptyPopTest()
90+
{
91+
var stack = new ArrayBasedStack<int>();
92+
93+
Assert.Catch(() => stack.Pop(), StackEmptyErrorMessage);
94+
}
95+
96+
[Test]
97+
public static void ShouldThrowStackEmptyExceptionOnEmptyPeekTest()
98+
{
99+
var stack = new ArrayBasedStack<int>();
100+
101+
Assert.Catch(() => stack.Peek(), StackEmptyErrorMessage);
102+
}
103+
83104
}
84105
}

DataStructures/ArrayBasedStack/ArrayBasedStack.cs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace DataStructures.ArrayBasedStack
1010
public class ArrayBasedStack<T>
1111
{
1212
private const int DefaultCapacity = 10;
13+
private const string StackEmptyErrorMessage = "Stack is empty";
1314

1415
/// <summary>
1516
/// <see cref="Array"/> based stack.
@@ -19,12 +20,16 @@ public class ArrayBasedStack<T>
1920
/// <summary>
2021
/// How many items are in the stack right now.
2122
/// </summary>
22-
private int count;
23+
private int top;
2324

2425
/// <summary>
2526
/// Initializes a new instance of the <see cref="ArrayBasedStack{T}"/> class.
2627
/// </summary>
27-
public ArrayBasedStack() => stack = new T[DefaultCapacity];
28+
public ArrayBasedStack()
29+
{
30+
stack = new T[DefaultCapacity];
31+
top = -1;
32+
}
2833

2934
/// <summary>
3035
/// Initializes a new instance of the <see cref="ArrayBasedStack{T}"/> class.
@@ -49,7 +54,7 @@ public ArrayBasedStack(IEnumerable<T> items)
4954
/// <summary>
5055
/// Gets the number of elements on the <see cref="ArrayBasedStack{T}"/>.
5156
/// </summary>
52-
public int Count => count;
57+
public int Top => top;
5358

5459
/// <summary>
5560
/// Gets or sets the Capacity of the <see cref="ArrayBasedStack{T}"/>.
@@ -70,30 +75,45 @@ public int Capacity
7075
/// <summary>
7176
/// Removes all items from the <see cref="ArrayBasedStack{T}"/>.
7277
/// </summary>
73-
public void Clear() => count = 0;
78+
public void Clear()
79+
{
80+
top = -1;
81+
Capacity = DefaultCapacity;
82+
}
7483

7584
/// <summary>
7685
/// Determines whether an element is in the <see cref="ArrayBasedStack{T}"/>.
7786
/// </summary>
7887
/// <param name="item">The item to locate in the <see cref="ArrayBasedStack{T}"/>.</param>
7988
/// <returns>True, if the item is in the stack.</returns>
80-
public bool Contains(T item) => Array.IndexOf(stack, item, 0, count) > -1;
89+
public bool Contains(T item) => Array.IndexOf(stack, item, 0, top + 1) > -1;
8190

8291
/// <summary>
8392
/// Returns the item at the top of the <see cref="ArrayBasedStack{T}"/> without removing it.
8493
/// </summary>
8594
/// <returns>The item at the top of the <see cref="ArrayBasedStack{T}"/>.</returns>
86-
public T Peek() => stack[count - 1];
95+
public T Peek()
96+
{
97+
if (top == -1)
98+
{
99+
throw new InvalidOperationException(StackEmptyErrorMessage);
100+
}
101+
102+
return stack[top];
103+
}
87104

88105
/// <summary>
89106
/// Removes and returns the item at the top of the <see cref="ArrayBasedStack{T}"/>.
90107
/// </summary>
91108
/// <returns>The item removed from the top of the <see cref="ArrayBasedStack{T}"/>.</returns>
92109
public T Pop()
93110
{
94-
var item = stack[count - 1];
95-
count = count - 1;
96-
return item;
111+
if (top == -1)
112+
{
113+
throw new InvalidOperationException(StackEmptyErrorMessage);
114+
}
115+
116+
return stack[top--];
97117
}
98118

99119
/// <summary>
@@ -102,13 +122,12 @@ public T Pop()
102122
/// <param name="item">The item to push onto the <see cref="ArrayBasedStack{T}"/>.</param>
103123
public void Push(T item)
104124
{
105-
if (count == Capacity)
125+
if (top == Capacity - 1)
106126
{
107-
Capacity = Capacity * 2;
127+
Capacity *= 2;
108128
}
109129

110-
stack[count] = item;
111-
count = count + 1;
130+
stack[++top] = item;
112131
}
113132
}
114133
}

0 commit comments

Comments
 (0)