2013-12-17 91 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(); 
    } 
}