2011-10-11 21 views
15

मैं जावा में एक स्टैक बनाना चाहता हूं, लेकिन आकार को ठीक करना चाहता हूं। उदाहरण के लिए, एक नया स्टैक बनाएं, आकार को 10 पर सेट करें, फिर जब मैं स्टैक पर आइटम को पुश करता हूं तो यह भर जाता है और जब यह दस तक भर जाता है, तो स्टैक में अंतिम आइटम को हटा दिया जाता है (हटाया जाता है)। मैं स्टैक का उपयोग करना चाहता हूं क्योंकि यह लिफो का उपयोग करता है और मेरी आवश्यकताओं को बहुत अच्छी तरह से फिट करता है।एक निश्चित आकार का ढेर बनाना

लेकिन सेटसेज() विधि जो वेक्टर से स्टैक विरासत में है, वास्तव में स्टैक के आकार को सीमित नहीं लगती है। मुझे लगता है कि स्टैक्स कैसे काम करता है, इस बारे में मुझे कुछ याद आ रहा है, या शायद ढेर को बाधित नहीं किया गया था, इसलिए यह असंभव है। कृपया मुझे शिक्षित करें!

+0

FYI करें setSize विधि वेक्टर से विरासत में मिली है, जिसका अर्थ है कि setSize कारण होगा nulls प्रदान की नई आकार को भरने के लिए जोड़े जाने के लिए, या नए आकार से परे मौजूदा वस्तुओं छोड़ दिए जाते हैं। आप सिद्धांत में ऐसा कर सकते हैं अगर (stack.size()> = 10) {stack.setSize (10); } जब भी आप ढेर पर धक्का देते हैं, लेकिन यह आपकी खुद की कस्टम कक्षा को लागू करना बेहतर होगा। – Thor84no

+0

मैंने मूल रूप से यह देखने के लिए कोशिश की कि यह काम करेगा या नहीं। यह अजीब है, लेकिन ऐसा लगता है कि जब मैं स्टैक पर setSize() करता हूं, तो यह आइटम के क्रम को उलट देता है और उन्हें वहां से छोटा करता है। इसलिए मैं हमेशा स्टैक में मूल 10 आइटम के साथ समाप्त होता हूं। इसी प्रकार, ऐसा करने के लिए एक और त्वरित/गंदा तरीका है (stack.size()> = 10) {stack.remove (0); } वही समस्या उत्पन्न होती है जहां यह आदेश को उलट देता है, इसलिए किसी कारण से 0 सूचकांक निकालना है। – koopaking3

+1

शायद इसका मतलब यह है कि अंतर्निहित कार्यान्वयन वास्तव में उस तरह से काम करता है और स्टैक विधियां आपको विपरीत क्रम में चीजें वापस कर रही हैं, जो वैसे भी बहुत समझ में आता है। – Thor84no

उत्तर

4

आप इस तरह एक बहुत ही सरल ढेर बना सकते हैं:

public class FixedStack<T> 
{ 
    private T[] stack; 
    private int size; 
    private int top; 

    public FixedStack<T>(int size) 
    { 
     this.stack = (T[]) new Object[size]; 
     this.top = -1; 
     this.size = size; 
    } 

    public void push(T obj) 
    { 
     if (top >= size) 
      throw new IndexOutOfBoundsException("Stack size = " + size); 
     stack[++top] = obj; 
    } 

    public T pop() 
    { 
     if (top < 0) throw new IndexOutOfBoundsException(); 
     T obj = stack[top--]; 
     stack[top + 1] = null; 
     return obj; 
    } 

    public int size() 
    { 
     return size; 
    } 

    public int elements() 
    { 
     return top + 1; 
    } 
} 
+0

मैं इस तरह कुछ करने के लिए समाप्त हो गया। धन्यवाद! – koopaking3

+0

मेमोरी लीक के लिए यहां एक संभावित क्षमता है। – mre

+1

@mre: ठीक है। रुको। मेरे द्वारा ठीक कर दिया जाएगा। किया हुआ। क्या यही आपका मतलब है? –

0

आप Stack उपclass कर सकते हैं और इस कस्टम व्यवहार को लागू करने के लिए उचित विधि (ओं) को ओवरराइड कर सकते हैं। और इसे एक स्पष्ट नाम देना सुनिश्चित करें (उदा। FixedStack)।

1

एक शुद्ध ढेर इसके आकार को सीमित नहीं करेगा, क्योंकि कई समस्याएं हल करने के लिए आपको पता नहीं है कि आपको कितने तत्वों की आवश्यकता होगी।

आप एक कस्टम स्टैक लिख सकते हैं जो आपके द्वारा वर्णित आवश्यकताओं को लागू करता है। हालांकि, यदि आप करते हैं तो आप लिफो को तोड़ देंगे। यदि अधिकतम आकार पूरा हो गया है, और आप स्टैक पर कुछ नया धक्का देते हैं, तो आप पहले जोड़े गए आइटम को खो देते हैं। तो यदि आप अपने स्टैक से आइटम पॉप अप करना शुरू करते हैं, तो आप कुछ याद करेंगे।

1

LinkedBlockingDeque एक साधारण विकल्प है। LinkedBlockingQueue(int) कन्स्ट्रक्टर का उपयोग करें जहां पैरामीटर आपकी स्टैक सीमा है।


आप मनाया के रूप में, Stack और Vector मॉडल असीम दृश्यों। setSize() विधि स्टैक/वेक्टर को छीनती है। यह डेटा संरचना को उस आकार से आगे बढ़ने से नहीं रोकता है।

+0

'LinkedBlockingDequeue' एक अच्छा विकल्प (+1) है, हालांकि सीमा तक पहुंचने पर यह केवल नए आइटम स्वीकार नहीं करेगा। यदि मैं ओपी को सही ढंग से समझता हूं, तो कतार/ढेर में केवल नवीनतम 10 तत्व होना चाहिए, इसलिए आपको अभी भी उस स्वचालित ड्रॉप को लागू करना होगा। – Thomas

+0

@ थॉमस - यदि आप 'add' विधियों का उपयोग करते हैं तो आपको इसके बजाय अपवाद मिलता है। लेकिन हाँ, यह ओपी की आवश्यकताओं से बिल्कुल मेल नहीं खाता है। –

0

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

1

यह असंभव नहीं है :) आपको बस अपना खुद का कार्यान्वयन प्रदान करना होगा।

मैं this जैसे रिंगबफर से शुरू करूंगा और तदनुसार इसे समायोजित कर दूंगा।

0

आप LinkedHashMap उपयोग कर सकते हैं और उसके removeEldestEntry विधि ओवरराइड:

public class FixedStack extends LinkedHashMap<Long, String> { 

    private final int capacity; 

    public FixedStack(int capacity) { 
     this.capacity = capacity; 
    } 

    @Override 
    protected boolean removeEldestEntry(final Map.Entry<Long, String> eldest) { 
     return super.size() > capacity; 
    } 
} 

और यह परीक्षण करने के लिए:

public static void main(String[] args) { 

     FixedStack stack = new FixedStack(10); 

     long added = 0; 
     for (Locale locale : Locale.getAvailableLocales()) { 
      if (locale.getDisplayCountry().length() > 0) { 
       stack.put(added, locale.getDisplayCountry()); 
       System.out.println(locale.getDisplayCountry()); 
       added++; 
      } 
     } 
     System.out.println(String.format(">>>>>>>>> %s added", 
       added)); 
     Iterator<Entry<Long, String>> iterator = stack.entrySet().iterator(); 
     while (iterator.hasNext()) { 
      System.out.println(iterator.next().getValue()); 
     } 
    } 

आपको बस यह तय करना होगा कि आप कुंजी के रूप में क्या उपयोग करना चाहते हैं, मैंने उदाहरण में एक साधारण काउंटर का उपयोग किया।

import java.util.Stack; 

public class SizedStack<T> extends Stack<T> { 
    private int maxSize; 

    public SizedStack(int size) { 
     super(); 
     this.maxSize = size; 
    } 

    @Override 
    public T push(T object) { 
     //If the stack is too big, remove elements until it's the right size. 
     while (this.size() >= maxSize) { 
      this.remove(0); 
     } 
     return super.push(object); 
    } 
} 

इस तरह इसका इस्तेमाल: SizedStack<Float> mySizedStack = new SizedStack<Float>(10);

19

यहाँ एक SizedStack प्रकार है कि Stack फैली हुई है। आकार के अलावा, यह किसी अन्य Stack की तरह काम करता है।

+1

यह बहुत अच्छा है! मैं 'if (this.size()> maxSize) 'if (this.size() == maxSize) के साथ' while (this.size()> maxSize)' को प्रतिस्थापित करने का सुझाव दूंगा, ताकि आकार जिसे आप 'SizedStack' प्रारंभ करना चाहते हैं, के लिए वास्तविक अधिकतम आकार होगा ढेर। –

+1

मैंने आपके द्वारा देखी गई एक-एक-एक त्रुटि का ख्याल रखने के लिए इसे 'while (this.size()> = maxSize) में बदल दिया है। धन्यवाद। हालांकि सुरक्षा उद्देश्यों के लिए यह अभी भी थोड़ी देर होनी चाहिए; क्या होगा यदि आकार किसी भी तरह maxSize से बड़ा हो गया? मुझे पता है कि यह असंभव प्रतीत होता है, लेकिन बग बग हैं :)। – Calvin

+1

मुझे आपकी पसंद का समर्थन करने की विचारशीलता पसंद है! अच्छी कॉल: डी –

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