2010-07-30 11 views
5

मैंने साक्षात्कार की शर्तों के तहत इसे तुरंत लिखा, मैं इसे समुदाय में पोस्ट करना चाहता था ताकि संभवतः यह देखने के लिए कि क्या इसके बारे में जाने के लिए एक बेहतर/तेज़/क्लीनर तरीका था। इसे कैसे अनुकूलित किया जा सकता है?एक स्टैक के इस सी # कार्यान्वयन के साथ कोई समस्या देखें?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Stack 
{ 
    class StackElement<T> 
    { 
     public T Data { get; set; } 
     public StackElement<T> Below { get; set; } 
     public StackElement(T data) 
     { 
      Data = data; 
     } 
    } 

    public class Stack<T> 
    { 
     private StackElement<T> top; 

     public void Push(T item)    
     { 
      StackElement<T> temp; 
      if (top == null) 
      { 
       top = new StackElement<T>(item); 
      } 
      else 
      { 
       temp = top; 
       top = new StackElement<T>(item); 
       top.Below = temp;     
      } 
     } 

     public T Pop() 
     { 
      if (top == null) 
      { 
       throw new Exception("Sorry, nothing on the stack"); 
      } 
      else 
      { 
       T temp = top.Data;     
       top = top.Below; 
       return temp; 
      }   
     } 

     public void Clear() 
     { 
      while (top != null) 
       Pop(); 
     } 

    } 


    class TestProgram 
    { 
     static void Main(string[] args) 
     { 
      Test1(); 
      Test2(); 
      Test3(); 
     } 

     private static void Test1() 
     { 
      Stack<string> myStack = new Stack<string>(); 
      myStack.Push("joe"); 
      myStack.Push("mike"); 
      myStack.Push("adam"); 

      if (myStack.Pop() != "adam") { throw new Exception("fail"); } 
      if (myStack.Pop() != "mike") { throw new Exception("fail"); } 
      if (myStack.Pop() != "joe") { throw new Exception("fail"); } 

     } 

     private static void Test3() 
     { 

      Stack<string> myStack = new Stack<string>(); 
      myStack.Push("joe"); 
      myStack.Push("mike"); 
      myStack.Push("adam"); 
      myStack.Clear(); 
      try 
      { 
       myStack.Pop(); 

      } 
      catch (Exception ex) 
      { 
       return; 
      } 

      throw new Exception("fail"); 
     } 

     private static void Test2() 
     { 
      Stack<string> myStack = new Stack<string>(); 
      myStack.Push("joe"); 
      myStack.Push("mike"); 
      myStack.Push("adam"); 

      if (myStack.Pop() != "adam") { throw new Exception("fail"); } 
      myStack.Push("alien"); 
      myStack.Push("nation"); 
      if (myStack.Pop() != "nation") { throw new Exception("fail"); } 
      if (myStack.Pop() != "alien") { throw new Exception("fail"); } 

     } 

    } 
} 
+0

मैं 'स्टैक एलिमेंट' रैपर की आवश्यकता के बारे में थोड़ा सा संदेह कर रहा हूं। – ChaosPandion

+2

@ChosPandion: यह वास्तव में एक लिंक-सूची है। – SLaks

+0

एक बहुत ही मामूली बात, उत्तर के लायक नहीं - मैं स्टैकएलेमेंट क्लास को स्टैक का एक निजी नेस्टेड क्लास बनाउंगा। –

उत्तर

3

आप बस एक सरणी का उपयोग कर सकते हैं। .NET सरणी विधियां वास्तव में तेज़ हैं।

public class Stack<T> 
{ 
    private const int _defaultSize = 4; 
    private const int _growthMultiplier = 2; 

    private T[] _elements; 
    private int _index; 
    private int _limit; 


    public Stack() 
    { 
     _elements = new T[_defaultSize]; 
     _index = -1; 
     _limit = _elements.Length - 1; 
    } 


    public void Push(T item) 
    { 
     if (_index == _limit) 
     { 
      var temp = _elements; 
      _elements = new T[_elements.Length * _growthMultiplier]; 
      _limit = _elements.Length - 1; 
      Array.Copy(temp, _elements, temp.Length); 
     } 
     _elements[++_index] = item; 
    } 

    public T Pop() 
    { 
     if (_index < 0) 
      throw new InvalidOperationException(); 

     var item = _elements[_index]; 
     _elements[_index--] = default(T); 
     return item; 
    } 

    public void Clear() 
    { 
     _index = -1; 
     Array.Clear(_elements, 0, _elements.Length); 
    } 
} 
+0

स्केल()? वो क्या है? – recursive

+0

@recurive - यह आवश्यकतानुसार सरणी को गतिशील रूप से विकसित करेगा। – ChaosPandion

+0

मुझे लगता है कि आपकी साफ़() विधि '_index = 0' होनी चाहिए, 'ऐरे' क्लीयर (...); 'वर्तमान कोड के साथ, ढेर अभी भी सोचेंगे कि साफ़ करने के लिए कॉल के बाद इसमें तत्व हैं () – recursive

4

मुझे लगता है कि स्पष्ट() विधि top = null; करने के लिए इसे बदल कर काफी तेज हो सकती है। पूरे ढेर को कचरा इकट्ठा किया जाएगा, और औसत समय में कोई लूप आवश्यक नहीं है।

2

एक लिंक्ड सूची के बजाय डेटा संरचना के रूप में गतिशील सरणी का उपयोग करने के लिए बेहतर हो सकता है। सरणी में संदर्भ के बेहतर इलाके होंगे क्योंकि तत्व एक-दूसरे के बगल में हैं। एक ढेर को मध्य, विभाजन आदि में तत्वों को हटाने की क्षमता की आवश्यकता नहीं होती है, इसलिए एक सरणी पर्याप्त होती है।

संबंधित मुद्दे