2010-01-13 17 views
9

का उपयोग किया है, हमने स्टैक क्लास के बारे में सभी को पढ़ा है या सुना है, लेकिन हम में से कई को शायद कभी भी LIFO ऑब्जेक्ट का उपयोग करने का कोई कारण नहीं मिला है। मैं असली दुनिया समाधानों को सुनने के लिए उत्सुक हूं जो इस वस्तु का उपयोग करते थे और क्यों।"स्टैक" ऑब्जेक्ट (.Net) के वास्तविक दुनिया का उपयोग आपने

http://msdn.microsoft.com/en-us/library/system.collections.stack.aspx

मैं हाल ही में एक उदाहरण है जहां एक प्रोग्रामर, जबकि एक श्रेणीबद्ध डेटा स्रोत traversing एक ढेर उपयोग अपने वर्तमान स्थिति का ट्रैक रखने के लिए देखा था। जैसे ही वह पदानुक्रम नीचे चला गया, उसने अपनी स्थिति पहचानकर्ता को ढेर पर धक्का दिया और जैसे ही वह वापस चले गए, उन्होंने स्टैक से वस्तुओं को पॉप किया। मैंने सोचा कि यह एक विशाल पदानुक्रम में अपनी वर्तमान स्थिति का ट्रैक रखने के लिए एक बहुत ही प्रभावशाली तरीका था। मैंने पहले कभी नहीं देखा था।

किसी और के पास कोई उदाहरण है?

+0

हाँ- पहले गहराई के लिए एक ढेर का उपयोग करना। क्या आप जानते थे कि आप पहली बार चौड़ाई के लिए कतार का उपयोग करते हैं? – RichardOD

+2

यह वास्तव में एक .NET विशिष्ट प्रश्न नहीं है। ढेर एक अमूर्त डेटा प्रकार हैं, और लोग उन्हें हर संभवतः (संभवतः) भाषा में उपयोग करते हैं। –

+0

मैं हर समय ढेर का उपयोग करता हूं। जब आवश्यक हो तो आप उनका उपयोग करें। –

उत्तर

16

मैंने उन्हें पूर्ववत और फिर से क्रियाओं का ट्रैक रखने के लिए उपयोग किया है।

interface ICommand 
{ 
    void Execute(); 
    void Undo(); 
    string Description { get; } 
} 

पूर्ववत करें या फिर प्रकार Stack<ICommand> के दोनों कर रहे हैं:

मैं इस तरह एक अंतरफलक कुछ का उपयोग करें। फिर मैं किसी दिए गए कार्य के लिए एक ठोस वर्ग बना देता हूं। कक्षा के कन्स्ट्रक्टर में, मैं किसी भी जानकारी में पास करता हूं जिसे मुझे पकड़ना होगा। Execute प्रारंभ में कार्रवाई करता है, और इसे भी फिर से शुरू करता है; Undo जाहिर है, इसे पूर्ववत करता है। यह इस तरह काम करता है:

  • एक क्रिया पूर्ववत करें: पूर्ववत स्टैक पॉप करें और फिर से स्टैक में जोड़ें।
  • एक पूर्ववत कार्रवाई फिर से करें: फिर से स्टैक पॉप करें और फिर से पूर्ववत स्टैक में जोड़ें।
  • एक नई कार्रवाई करें: पूर्ववत स्टैक में जोड़ें और फिर से स्टैक साफ़ करें (क्योंकि राज्य अब संगत नहीं है)।

मैंने पाया कि आपको यह ध्यान रखना होगा कि आप वास्तव में क्या कर रहे थे पूर्ववत कर रहे हैं। उदाहरण के लिए, कहें कि आपके पास दो सूची बॉक्स वाला यूआई है, और इसमें प्रत्येक में पांच आइटम हैं। आपकी कार्रवाई बाएं सूची में सब कुछ सही सूची में स्थानांतरित करने के लिए बटन पर क्लिक करना हो सकता है (इसलिए अब इसमें दस है, और बाएं सूची में शून्य है)।

पूर्ववत कार्रवाई सब कुछ वापस ले जाने के लिए नहीं है; पूर्ववत कार्रवाई केवल उन पांचों को वापस ले जाना है जिन्हें आप वास्तव में स्थानांतरित करते हैं, और दूसरों को छोड़ देते हैं।

7

Stacks are used whenever a stored procedure/sub-routine is called to store local variables and return address.

ढेर अभिव्यक्ति मूल्यांकन के लिए उपयोग किया जाता है (एक कैलकुलेटर, या अपने संकलक में जैसे), पहली अभिव्यक्ति RPN में बदल जाती है तो एक साधारण ढेर मशीन का मूल्यांकन किया जाता है। यह निम्नानुसार काम करता है, जब आप एक ऑपरेंड को स्टैक पर धक्का देते हैं। जब आप एक ऑपरेटर पॉप ऑपरेंड देखते हैं और मूल्यांकन करते हैं।

example 

5 6 + 3 * 

steps- 
see 5 push 5 
see 6 push 6 
see + pop 2 times and apply + get 11 push 11 
see 3 push 3 
see * pop 2 times and apply get 33 push 33 

result is on the top of the stack. 
+0

आप सामान्य रूप से इस उत्तर का विस्तार कर सकते हैं कि भाषा दुभाषिया अक्सर एक ढेर का उपयोग करते हैं। – Toad

+0

गलती ... मैंने कहा कि उनका उपयोग अभिव्यक्ति मूल्यांकन के लिए किया जाता है - इस प्रकार अभिव्यक्ति मूल्यांकन करने वाले कुछ भी उनका उपयोग करते हैं, फिर मैंने दो उदाहरण दिए। – Hogan

+0

@downvoter: – Hogan

5

यदि आपके पास एक रिकर्सिव एल्गोरिदम है, तो आप आम तौर पर उन्हें एक स्टैक का उपयोग करके फिर से लिख सकते हैं।

+0

हमम नहीं था .... मुझे नहीं लगता कि यह एक पुनः लिखना है। यह एक ही बात है। – Hogan

+0

सच है, लेकिन कभी-कभी यह आपको कई पैरामीटरों को पार करने पर बचाता है जिन्हें आप अब स्थानीय – Toad

+2

-1 रख सकते हैं, यह वास्तविक दुनिया नहीं है। यदि यह पूंछ-पुनरावर्ती है, तो आप बस थोड़ी देर के लूप का उपयोग करते हैं; अन्यथा, स्टैक ऑब्जेक्ट का उपयोग करना रिकर्सन का उपयोग करने से कहीं अधिक काम (और धीमी) है। –

0

मैं काफी एक व्युत्क्रम समय फैशन में स्थितियों का ट्रैक रखने के बहु-क्रम aplications में उपयोगी ढेर लगता है ...

(के बाद से पुनरावर्ती एल्गोरिदम परोक्ष पहले से ही एक ढेर का उपयोग करें) हर धागे में एक तुल्यकालन साझा एक स्थिति संदेश डालता है ढेर और आपके पास क्या हुआ है इसका एक "ब्रेडक्रंब" है।

काफी नेट नहीं लेकिन ... यह मेरी राय है =)

+0

चूंकि इस उदाहरण में चीजों का क्रम कोई फर्क नहीं पड़ता है, इसलिए कतार – Toad

+0

पर काम करेगी, यदि आप ब्रेडक्रंब फैशन में चीजों को डीबग करना चाहते हैं तो यह महत्वपूर्ण है। हर कदम उठाने की तरह आप पीछे की ओर किया। मुझे लगता है कि उसने उदाहरणों के बारे में पूछा कि हम में से कोई भी उपयोगी पाया ... =) –

0

यहाँ के एक कार्यान्वयन है एक गहरी, जहां एक ढेर तुलना की जा रही मौजूदा वस्तु के लिए पथ का ट्रैक रखने के लिए किया जाता है की तुलना करें।

C# implementation of deep/recursive object comparison in .net 3.5

मैं भी विशेष रूप से एक्सएमएल नोड्स के लिए xpath बयान पैदा करने के साथ काम कर कोड के समान प्रकार में यह प्रयोग किया है।

1

मैंने छवि प्रसंस्करण के लिए ढेर का उपयोग किया है, जहां "प्रसंस्करण भाषा" को URL में निर्दिष्ट किया जाना चाहिए। एक स्टैक-आधारित फॉर्म आपको आसानी से पर्स, आसानी से सोचने वाले फॉर्म में संचालन के पेड़ का प्रतिनिधित्व करने देता है।

देखें: एक Z- मशीन दुभाषिया तीन अलग-अलग ढेर चाहिए लागू करने के लिए:

http://www.hackification.com/2008/10/29/stack-based-processing-part-1/

और

http://www.hackification.com/2008/10/29/stack-based-processing-part-2/

0

उजागर करना क्या अन्य लोगों पर टिप्पणी कर रहे हैं एक विशिष्ट उदाहरण प्रदान करने के लिए इस्तेमाल किया गया। एक कॉल स्टैक, और कुछ अलग प्रकार के ऑब्जेक्ट स्टैक्स। (विशिष्ट आवश्यकताओं को here. पाया जा सकता है) ध्यान दें कि, इन सभी उदाहरणों की तरह, स्टैक का उपयोग करते समय सख्ती से आवश्यक, यह स्पष्ट विकल्प है।

कॉल स्टैक सबराउटिन को रिकर्सिव कॉल का ट्रैक रखता है, जबकि ऑब्जेक्ट स्टैक का उपयोग आंतरिक वस्तुओं का ट्रैक रखने के लिए किया जाता है।

3

आप संतुलित टोकन की आवश्यकता वाले स्ट्रिंग इनपुट को सत्यापित कर सकते हैं। लिस्प सोचें:

stack.Push("(") 

फिर जब आप एक बंद कोष्ठक मारा:

(+ (- 3 2) (+ (+ 4 5) 11)) 

जब आप एक प्रारंभिक कोष्ठक मारा

stack.Pop() 

अगर कोई टोकन अपने ढेर में छोड़ दिया जाता है जब आप 'किया, यह संतुलित नहीं है।

आप प्रशंसक प्राप्त कर सकते हैं और एचटीएमएल जैसे इनपुट में उचित घोंसले को मान्य कर सकते हैं। एक उच्च काल्पनिक उदाहरण में:

//see opening body 
stack.Push("body") 

//see opening div 
stack.Push("div") 

//see opening p 
stack.Push("p") 

///see closing div 
if(!stack.Pop().Equal("div")){ 
    //not balanced 
} 
+0

यह XML दस्तावेज़ों को पार्स करने के लिए भी है – Scoregraphic

1

एक वास्तविक जीवन प्रयोग में, एक उपसंहार जनरेटर वर्ग एक "current_font" राज्य, किसी भी आपरेशन जो पाठ आकर्षित के लिए फ़ॉन्ट के रूप में इस्तेमाल किया है। कभी-कभी फ़ंक्शन को अस्थायी रूप से फ़ॉन्ट सेट करने की आवश्यकता होती है, लेकिन फिर यह उस तरीके से वापस जाती है। हम सिर्फ बचाने के लिए और फॉन्ट बहाल करने के लिए एक अस्थायी चर इस्तेमाल कर सकते हैं:

def draw_body 
    old_font = ps.get_font 
    ps.set_font('Helvetica 10') 
    draw_top_section 
    draw_bottom_section 
    ps.set_font(old_font) 
end 

लेकिन तीसरी बार से आप यह कर लें तो आप अपने आप को दोहरा को रोकने के लिए चाहता हूँ।

class PS 

    def save_font 
    old_font = get_font 
    end 

    def restore_font 
    set_font(old_font) 
    end 

end 

अब फोन करने वाले हो जाता है:: तो चलो ps वस्तु बचाने के लिए और हमारे लिए फ़ॉन्ट को बहाल करने देते हैं

def draw_body 
    ps.save_font 
    ps.set_font('Helvetica 10') 
    draw_top_section 
    draw_bottom_section 
    ps.restore_font 
end 

यह ठीक काम करता है, जब तक हम सबरूटीन्स से बुलाया में से एक के अंदर एक ही पैटर्न का उपयोग draw_page:

def draw_top_section 
    ps.save_font 
    ps.set_font('Helvetica-bold 14') 
    # draw the title 
    ps.restore_font 
    # draw the paragraph 
end 

draw_top_section फोन करता है "save_font", यह है कि draw_page द्वारा बचा लिया गया था फॉन्ट clobbers।

def PS 

    def push_font 
    font_stack.push(get_font) 
    end 

    def pop_font 
    set_font(font_stack.pop) 
    end 

end 

और कॉल करने वालों में:: यह एक ढेर का उपयोग करने का समय है

def draw_top_section 
    ps.push_font 
    ps.set_font('Helvetica-bold 14') 
    # draw the title 
    ps.pop_font 
    # draw the body 
end 

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

0

कंप्यूटर ग्राफिक्स क्लास (.NET नहीं) में हमने स्क्रीन पर खींची गई वस्तुओं का ट्रैक रखने के लिए एक स्टैक का उपयोग किया। इसने प्रत्येक ऑब्जेक्ट के लिए स्क्रीन पर सभी ऑब्जेक्ट्स को फिर से खींचा जाने के साथ-साथ प्रत्येक ऑब्जेक्ट के ऑर्डर या "जेड-लेयर" को ट्रैक रखने की इजाजत दी, इसलिए जब वे चले गए तो वे अन्य ऑब्जेक्ट्स ओवरलैप कर सकते थे।

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