Reputation: 377
I am trying to get my push and pop methods working but can't seem to be able to. With the Push method I think it is something to do with nextfree but I'm not to sure. Also with the Pop method I am not to sure how to do it, I will put the pseudo code I have for it below my actual code. Here is my code:
class Program
{
private string[] Stack = new string[5];
int nextFree = 3;
public Program()
{
Stack = new string[5];
Stack[0] = "Greg";
Stack[1] = "Matt";
Stack[2] = "Jack";
Stack[3] = "Fred";
}
static void Main(string[] args)
{
Program prog = new Program();
do
{
prog.DisplayMenu();
}
while (true);
}
public void DisplayMenu()
{
Int32 userInput = 0;
Console.WriteLine("Linear Stack");
Console.WriteLine("1: Add to stack");
Console.WriteLine("2: Delete from stack");
userInput = Int32.Parse(Console.ReadLine());
switch (userInput)
{
case 1:
this.Push();
break;
case 2:
this.Pop();
break;
}
}
public void Push()
{
if (nextFree == Stack.Length)
{
Console.WriteLine("Stackoverflow, to many elements for the stack");
Console.ReadLine();
}
else
{
Console.WriteLine("Please enter a name to be added");
string userInput = Console.ReadLine();
nextFree++;
Stack[nextFree] = userInput;
}
this.list();
}
public void Pop()
{
if (nextFree == -1)
{
Console.WriteLine("Stack is empty");
Console.ReadLine();
}
else
{
nextFree--;
}
this.list();
}
public void list()
{
foreach (string s in Stack)
{
Console.Write(s + " ");
}
Console.WriteLine();
}
}
}
Pop pseudo code:
If Stack is empty
Then error
Else
Return Stack[TopOfStackPointer]
Decrement TopOfStackPointer
EndIF
UPDATE: The Push method works now with the nextFree being initiated with the value 3.
Upvotes: 3
Views: 22057
Reputation: 27001
Late answer - you can easily implement Push and Pop for C# the same way as you have them in Javascript/TypeScript already: There they are working with arrays. The advantage is that you don't need to care about duplicate values - new elements are just appended to the array.
In C#, you can do it like this (note that there is one difference to JavaScript for Push - I am returning the array instead of just the new length, because I think that makes more sense):
void Main()
{
T[] Push<T>(ref T[] ar, params T[] items)
{
var arLength=ar.Length;
Array.Resize(ref ar, arLength + items.Length);
for (int i = arLength, j=0; i < arLength + items.Length; i++, j++)
{
ar[i] = items[j];
}
return ar;
}
T Pop<T>(ref T[] ar)
{
T item = default(T);
if (ar.Length > 0)
{
var tmp = ar.ToList(); item = tmp.LastOrDefault();
Array.Resize(ref ar, ar.Length - 1);
};
return item;
}
// Example 1: Create a numeric array
var arr = new[] { 1, 2, 3, 4 };
// Push 5, 6, 7 to the end
Push(ref arr, 5, 6, 7).Dump();
// Pop the last element (7)
Pop(ref arr).Dump(); arr.Dump();
// Example 2: "Stack" array
var Stack=new[] {"Greg", "Matt"};
Push(ref Stack, "Jack", "Fred"); Stack.Dump();
var elem=Pop(ref Stack); elem.Dump(); Stack.Dump();
}
These functions are generic, you can use it with every type of array.
Usage examples:
var emptyIntArray = new int[0]; // empty array: specify type + length=0
var emptyStrArray = new string[0]; // empty array: specify type + length=0
var arr = new[] { 1, 2, 3, 4 }; // example array. can be strings as well!
Pop:
Pop(ref arr); // removes the item with highest index
var item = Pop(ref arr); // removes the item with highest index, returns it
Pop(ref emptyIntArray); // returns 0 (default for int)
Pop(ref emptyStrArray); // returns null (default for string)
Push:
Push(ref arr, 5); // adds element 5 (increases array size by 1)
Push(ref arr, 6, 7, 8); // adds elements 6, 7, 8 (increases array size by 3)
var newLen = Push(ref arr, 9).Length; // adds element 9, returns new length
Note I am using the ref
parameter, because I don't want to waste memory by creating a copy of the entire array. That works by resizing the array. Because of the ref
parameter, Push
and Pop
cannot be extension methods.
Output of the program example:
Dumping object(Int32[])
[1,2,3,4,5,6,7]
Dumping object(Int32)
7
Dumping object(Int32[])
[1,2,3,4,5,6]
Dumping object(String[])
[Greg,Matt,Jack,Fred]
Dumping object(String)
Fred
Dumping object(String[])
[Greg,Matt,Jack]
Upvotes: 0
Reputation: 1
I like the idea of the MStack class (see Raz Megrelidze's answer). However, the problem with a one dimensional list to implement a stack, is that it cannot handle duplicate values. So in many cases it is a failing stack.
So here is my Dictionary variation, which can handle duplicates.
public class MStack<T> : IEnumerable<T>
{
private readonly Dictionary<int, T> stack = new Dictionary<int, T>();
public void Push(T item)
{
stack.Add(stack.Count, item);
}
public T Pop()
{
var item = Peek();
stack.Remove(stack.Count - 1);
return item;
}
public T Peek()
{
return stack[stack.Count - 1];
}
public int Count { get { return stack.Count; } }
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < stack.Count; i++)
yield return Peek();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Upvotes: 0
Reputation: 3060
Here's my implementation of stack.
public class MStack<T> : IEnumerable<T>
{
private readonly List<T> stack = new List<T>();
public void Push(T item)
{
stack.Add(item);
}
public T Pop()
{
var item = Peek();
stack.Remove(Peek());
return item;
}
public T Peek()
{
return stack[stack.Count - 1];
}
public int Count { get { return stack.Count; } }
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < stack.Count; i++)
yield return Peek();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Upvotes: 1
Reputation: 9201
Your Pop
method is almost complete, the last step you need is to actually remove the value from the array before decrementing the index, to "pop" it out. You can do this by setting the previous value to null
.
public void Pop()
{
if (nextFree == -1)
{
Console.WriteLine("Stack is empty");
Console.ReadLine();
}
else
{
Stack[nextFree] = null;
nextFree--;
}
this.list();
}
You can also get the value just before to show what have been popped by adding
string value = Stack[nextFree];
Console.WriteLine("Just popped value: " + value);
before setting it to null
It is not necessary here to actually return it like in your pseudocode, since you're not using the value outside. If you need it, consider changing the code to
public string Pop()
{
string value = string.Empty;
if (nextFree == -1)
{
Console.WriteLine("Stack is empty");
Console.ReadLine();
}
else
{
value = Stack[nextFree];
Stack[nextFree] = null;
nextFree--;
}
this.list();
return value;
}
Notice the return type also changed from void
to string
.
Upvotes: 2
Reputation: 39457
Try this code. Also make sure to compare with your version to see where your problems were.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication12
{
class Program
{
private string[] Stack = new string[5];
private int nextFree;
public Program()
{
Stack = new string[10];
Stack[0] = "Greg";
Stack[1] = "Matt";
Stack[2] = "Jack";
Stack[3] = "Fred";
nextFree = 4;
}
static void Main(string[] args)
{
Program prog = new Program();
do
{
prog.DisplayMenu();
}
while (true);
}
public void DisplayMenu()
{
Int32 userInput = 0;
Console.WriteLine("Linear Stack");
Console.WriteLine("1: Add to stack");
Console.WriteLine("2: Delete from stack");
String s = Console.ReadLine().Trim();
try
{
userInput = Int32.Parse(s);
}
catch (Exception)
{
userInput = 1;
}
switch (userInput)
{
case 1:
this.Push();
break;
case 2:
this.Pop();
break;
}
}
public void Push()
{
if (nextFree == Stack.Length)
{
Console.WriteLine("Stackoverflow, to many elements for the stack");
Console.ReadLine();
}
else
{
Console.WriteLine("Please enter a name to be added");
string userInput = Console.ReadLine();
Stack[nextFree] = userInput;
nextFree++;
}
this.List();
}
public String Pop()
{
if (nextFree == 0)
{
Console.WriteLine("Stack is empty");
return null;
}
else
{
String res = Stack[nextFree - 1];
nextFree--;
this.List();
return res;
}
}
public void List()
{
for (int k = 0; k < nextFree; k++)
{
Console.Write(this.Stack[k] + " ");
}
Console.WriteLine();
}
}
}
Upvotes: 2
Reputation: 6260
You need to instantiate the value of nextFree to 4 when you first start (since you already have 4 items in your stack).
When checking to see if the value of nextFree is out of bounds of not, you need to remember that array indexes are zero based (i.e. they start at 0). So your condition should be:
if(nextFree >= Stack.Length - 1)
Upvotes: 4