我正在努力让我的推送和流行方法正常工作,但似乎无法做到。使用Push方法,我认为这与nextfree有关,但我不确定。另外,使用Pop方法,我不确定如何做,我将把我的伪代码放在我的实际代码下面。 这是我的代码:
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伪代码:
If Stack is empty
Then error
Else
Return Stack[TopOfStackPointer]
Decrement TopOfStackPointer
EndIF
更新: Push方法现在可以使用值3启动nextFree。
答案 0 :(得分:4)
首次启动时,您需要将nextFree的值实例化为4(因为您的堆栈中已有4个项目)。
当检查nextFree的值是否超出not的范围时,您需要记住数组索引是基于零的(即它们从0开始)。所以你的情况应该是:
if(nextFree >= Stack.Length - 1)
答案 1 :(得分:2)
试试这段代码。还要确保与您的版本进行比较,以了解您的问题所在。
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();
}
}
}
答案 2 :(得分:2)
您的Pop
方法已基本完成,您需要的最后一步是在递减索引之前实际从数组中删除值,以“弹出”它。您可以将之前的值设置为null
。
public void Pop()
{
if (nextFree == -1)
{
Console.WriteLine("Stack is empty");
Console.ReadLine();
}
else
{
Stack[nextFree] = null;
nextFree--;
}
this.list();
}
您也可以通过添加
来获取之前显示的内容string value = Stack[nextFree];
Console.WriteLine("Just popped value: " + value);
将其设置为null
这里没有必要像你的伪代码那样实际返回它,因为你没有使用外面的值。如果需要,请考虑将代码更改为
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;
}
请注意,返回类型也从void
更改为string
。
答案 3 :(得分:1)
这是我的堆栈实现。
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();
}
}
答案 4 :(得分:0)
我喜欢MStack课程的想法(参见Raz Megrelidze的回答)。但是,实现堆栈的一维列表的问题在于它无法处理重复值。因此,在许多情况下,它是一个失败的堆栈。
所以这是我的词典变体,它可以处理重复。
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();
}
}
答案 5 :(得分:0)
最新答案-您可以像在Javascript / TypeScript中一样使用 Push and Pop for C#来轻松实现它们:数组正在使用它们。优点是您不必关心重复的值-新元素仅附加到数组中。
在 C#中,您可以这样操作(请注意,JavaScript与Push语言有一个区别-我返回的是数组,而不仅仅是新的长度,因为我认为这样做更有意义):
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();
}
这些函数是通用的,您可以将其用于每种类型的数组。
用法示例:
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(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(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
注意,我正在使用 ref
参数,因为我不想通过创建整个阵列的副本来浪费内存。这可以通过调整数组大小来实现。由于存在ref
参数,因此Push
和Pop
不能作为扩展方法。
程序示例的输出:
转储对象(Int32 [])
[1,2,3,4,5,6,7]
转储对象(Int32)
7
转储对象(Int32 [])
[1,2,3,4,5,6]
转储对象(字符串[])
[格雷格,马特,杰克,弗雷德]
转储对象(字符串)
弗雷德
转储对象(字符串[])
[格雷格,马特,杰克]