O (1) को हटाने और बदलने के लिए आप किन डेटा संरचनाओं का उपयोग कर सकते हैं? या जब आप कहा संरचनाओं की आवश्यकता है तो आप परिस्थितियों से कैसे बच सकते हैं?
ST
हास्केल में इकाई इस उत्कृष्ट करता है।
O (1) को हटाने और बदलने के लिए आप किन डेटा संरचनाओं का उपयोग कर सकते हैं? या जब आप कहा संरचनाओं की आवश्यकता है तो आप परिस्थितियों से कैसे बच सकते हैं?
ST
हास्केल में इकाई इस उत्कृष्ट करता है।
जवाबों:
कई प्रकार की समस्याओं के लिए निरंतर समय या (जैसे कुछ सीमित मामलों के लिए, जैसे कि कतारें ) लगातार अपडेट प्राप्त करने के लिए आलस्य और अन्य चाल का उपयोग करने वाले डेटा संरचनाओं का एक विशाल सरणी है। क्रिस ओकासाकी की पीएचडी थीसिस "विशुद्ध रूप से कार्यात्मक डेटा संरचनाएं" और एक ही नाम की पुस्तक एक प्रमुख उदाहरण (शायद पहला प्रमुख एक) है, लेकिन क्षेत्र तब से उन्नत हुआ है । ये डेटा संरचनाएं आमतौर पर न केवल इंटरफ़ेस में विशुद्ध रूप से कार्यात्मक हैं, बल्कि शुद्ध हास्केल और समान भाषाओं में भी लागू की जा सकती हैं, और पूरी तरह से निरंतर हैं।
इनमें से किसी भी उन्नत उपकरण के बिना, सरल संतुलित द्विआधारी खोज पेड़ लॉगरिदमिक-टाइम अपडेट देते हैं, इसलिए म्यूटेबल मेमोरी को सबसे खराब लॉगरिदमिक धीमा के साथ सिम्युलेट किया जा सकता है।
अन्य विकल्प हैं, जिन्हें धोखा माना जा सकता है, लेकिन कार्यान्वयन के प्रयास और वास्तविक दुनिया के प्रदर्शन के संबंध में बहुत प्रभावी हैं। उदाहरण के लिए, रैखिक प्रकार या विशिष्टता प्रकार एक वैचारिक रूप से शुद्ध भाषा के लिए कार्यान्वयन रणनीति के रूप में इन-प्लेस अद्यतन की अनुमति देते हैं, कार्यक्रम को पिछले मूल्य (स्मृति जो उत्परिवर्तित होगा) पर रोक से रोकते हैं। यह लगातार डेटा संरचनाओं की तुलना में कम सामान्य है: उदाहरण के लिए, आप राज्य के सभी पिछले संस्करणों को संग्रहीत करके आसानी से पूर्ववत लॉग नहीं बना सकते हैं। यह अभी भी एक शक्तिशाली उपकरण है, हालांकि AFAIK अभी तक प्रमुख कार्यात्मक भाषाओं में उपलब्ध नहीं है।
कार्यात्मक सेटिंग में उत्परिवर्तित अवस्था को सुरक्षित रूप से पेश करने का एक अन्य विकल्प ST
हास्केल में मोनाड है। इसे बिना म्यूटेशन के लागू किया जा सकता है और बैरिंग unsafe*
फ़ंक्शंस में, यह ऐसा व्यवहार करता है जैसे कि यह केवल एक फैंसी रैपर था, जो लगातार डेटा संरचना को अव्यवस्थित रूप से गुज़ारता है (cf. State
)। लेकिन कुछ प्रकार की प्रणाली चालबाजी के कारण जो मूल्यांकन के आदेश को लागू करता है और बचने से रोकता है, इसे सभी प्रदर्शन लाभ के साथ इन-प्लेस म्यूटेशन के साथ सुरक्षित रूप से लागू किया जा सकता है।
एक सस्ता उत्परिवर्ती संरचना तर्क ढेर है।
विशिष्ट SICP शैली फैक्टरियल गणना पर एक नज़र डालें:
(defn fac (n accum)
(if (= n 1)
accum
(fac (- n 1) (* accum n)))
(defn factorial (n) (fac n 1))
जैसा कि आप देख सकते हैं, fac
तेजी से बदलते उत्पाद को समाहित करने के लिए दूसरे तर्क को एक उत्परिवर्तनीय संचायक के रूप में उपयोग किया जाता है n * (n-1) * (n-2) * ...
। कोई भी परिवर्तनशील चर दृष्टि में नहीं है, हालांकि, और अनजाने में संचायक को बदलने का कोई तरीका नहीं है, उदाहरण के लिए दूसरे धागे से।
यह, एक सीमित उदाहरण है।
आप हेड नोड के सस्ते प्रतिस्थापन के साथ अपरिवर्तनीय लिंक प्राप्त कर सकते हैं (और सिर से शुरू होने वाले किसी भी भाग को विस्तार देकर): आप बस नए हेड पॉइंट को उसी अगले नोड पर बनाते हैं जैसे पुराने हेड ने किया था। यह कई सूची-प्रसंस्करण एल्गोरिदम (कुछ भी fold
आधारित) के साथ अच्छी तरह से काम करता है ।
आप HAMTs पर आधारित सहयोगी सरणियों से बहुत अच्छा प्रदर्शन प्राप्त कर सकते हैं । तार्किक रूप से आप एक नया सहयोगी सरणी प्राप्त करते हैं जिसमें कुछ मुख्य-मूल्य जोड़ी (जोड़े) बदल गए हैं। कार्यान्वयन पुराने और नए बनाए गए ऑब्जेक्ट के बीच अधिकांश सामान्य डेटा साझा कर सकता है। हालांकि यह ओ (1) नहीं है; आमतौर पर आपको लॉगरिदमिक कुछ मिलता है, कम से कम सबसे खराब स्थिति में। दूसरी ओर, अपरिवर्तनीय पेड़, आमतौर पर उत्परिवर्तित पेड़ों की तुलना में किसी भी प्रदर्शन के दंड का शिकार नहीं होते हैं। बेशक, इसके लिए कुछ मेमोरी ओवरहेड की आवश्यकता होती है, आमतौर पर निषेधात्मक से दूर।
एक अन्य दृष्टिकोण इस विचार पर आधारित है कि यदि कोई पेड़ किसी जंगल में गिरता है और कोई उसे नहीं सुनता है, तो उसे ध्वनि उत्पन्न करने की आवश्यकता नहीं है। यही है, अगर आप यह साबित कर सकते हैं कि उत्परिवर्तित अवस्था कभी भी कुछ स्थानीय गुंजाइश नहीं छोड़ती है, तो आप इसके भीतर डेटा को सुरक्षित रूप से बदल सकते हैं।
Clojure है यात्रियों कि परिवर्तनशील अपरिवर्तनीय डेटा संरचनाओं कि बाहर स्थानीय गुंजाइश रिसाव नहीं है की 'छाया' कर रहे हैं। कुछ समान हासिल करने के लिए क्लीन यूनिकिक्स का उपयोग करता है (यदि मुझे सही याद है)। जंग सांख्यिकीय रूप से जांचे गए अद्वितीय बिंदुओं के साथ समान कार्य करने में मदद करता है।
ref
और उन्हें एक निश्चित दायरे में बांटने का एक तरीका है । देखें IORef
या STRef
। और फिर निश्चित रूप से TVar
s और MVar
s हैं जो समान हैं लेकिन sane समवर्ती शब्दार्थ के साथ ( TVar
s s और mutex MVar
s के लिए आधारित हैं )
आप जो पूछ रहे हैं वह थोड़ा बहुत व्यापक है। ओ (1) किस स्थिति से हटाने और प्रतिस्थापन? एक अनुक्रम के प्रमुख? पुंछ? एक मनमाना पद? उपयोग करने के लिए डेटा संरचना उन विवरणों पर निर्भर करती है। उस ने कहा, 2-3 फिंगर ट्रीज़ एक सबसे बहुमुखी लगातार डेटा संरचनाओं की तरह प्रतीत होते हैं:
हम 2-3 अंगुल वृक्षों को प्रस्तुत करते हैं, निरंतर स्थिर समय में सिरों तक पहुंच का समर्थन करने वाले लगातार अनुक्रमों का एक कार्यात्मक प्रतिनिधित्व, और छोटे टुकड़े के आकार में लघुगणक में समतल और विभाजन।
(...)
इसके अलावा, एक सामान्य रूप में विभाजन ऑपरेशन को परिभाषित करके, हम एक सामान्य उद्देश्य डेटा संरचना प्राप्त करते हैं जो अनुक्रम, प्राथमिकता कतार, खोज ट्री, प्राथमिकता खोज कतार और बहुत कुछ के रूप में काम कर सकता है।
आम तौर पर लगातार डेटा संरचनाओं में मनमाना पदों में फेरबदल करने पर लॉगरिदमिक प्रदर्शन होता है। यह एक समस्या हो सकती है या नहीं भी हो सकती है, क्योंकि O (1) एल्गोरिथ्म में निरंतरता अधिक हो सकती है, और लॉगरिदमिक मंदी एक धीमी समग्र एल्गोरिथ्म में "अवशोषित" हो सकती है।
इससे भी महत्वपूर्ण बात, लगातार डेटा संरचनाएं आपके कार्यक्रम के बारे में तर्क करना आसान बनाती हैं, और यह हमेशा आपके ऑपरेशन का डिफ़ॉल्ट तरीका होना चाहिए। जब भी संभव हो, आपको लगातार डेटा संरचनाओं का समर्थन करना चाहिए, और केवल एक बार परिवर्तन किए जाने के बाद ही एक परिवर्तनशील डेटा संरचना का उपयोग करें और निर्धारित करें कि लगातार डेटा संरचना एक प्रदर्शन अड़चन है। और कुछ भी समय से पहले अनुकूलन है।