2013-12-17 92 views
1

我想让我的推送和流行方法工作,但似乎无法做到。通过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(); 
     } 



    } 
} 

流行的伪代码:

If Stack is empty 
Then error 
Else 
Return Stack[TopOfStackPointer] 
Decrement TopOfStackPointer 
EndIF 

UPDATE: 现在的Push方法的工作原理与nextFree正与值3

+1

没有错误的描述,它几乎不可能帮助你。 –

+0

@ Dan-o推送方法没有错误,只是在我使用它的时候,添加的任何名字都会替换已经在堆栈中的名字。另外对于Pop方法,即使使用提供的伪代码,我也不确定如何操作。 – user2852418

回答

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); 

弹出设置之前,为空

这是没有必要在这里居然返回它喜欢你的伪代码,因为你没有使用外部的值。如果你需要它,考虑代码更改为

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

+0

我在哪里启动“值”,因为它会抛出当前上下文中不存在的错误。 – user2852418

+0

@ user2852418的确,我的不好,编辑了答案。它是在if条件中声明的,你必须把它放在外面。 –

+0

谢谢,它现在可以工作。 – user2852418

4

您需要实例启动当你第一次启动时nextFree的值为4(因为你的堆栈中已经有4个物品)。

当检查nextFree的值是否超出界限时,您需要记住数组索引是从零开始的(即它们从0开始)。所以你的条件应该是:

if(nextFree >= Stack.Length - 1) 
+0

当我将nextFree初始化为4.我在'Stack [nextFree] = userInput;'中得到一个错误,它说“索引超出了数组的范围”。 – user2852418

+1

实际上它应该被初始化为'3',因为在设置值之前你是_incrementing_'nextFree'。我会建议增加_after_增加或更改成员名称为'lastIndex' –

+0

@ user2852418这是因为你正在做'私人字符串[]堆栈=新字符串[5];'。堆栈实际上应该是它自己的类型,并且您应该根据需要动态调整后备数组的大小(即.NET堆栈的工作方式)。将它更改为3只是为了您的第一次推动才能解决它。如果你连续两次打电话,你会得到同样的错误。 – evanmcdonnal

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(); 
       } 
      } 

     } 
+0

谢谢,我可以看到为什么Pop方法不起作用。 – user2852418

+0

@ user2852418好的,祝你好运。 –

0

这是我的堆栈实现。

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(); 
    } 
} 
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(); 
    } 
}