2012-05-03 21 views
7

मैं हास्केल में एक डेटा संरचना की तलाश में हूं जो तेजी से अनुक्रमण और तेजी से संलग्न दोनों का समर्थन करता है। यह एक यादगार समस्या के लिए है जो रिकर्सन से उत्पन्न होता है।हास्केल: ओ (1) के साथ डेटास्ट्रक्शन और ओ (1) अनुक्रमण?

वेक्टर सी ++ में काम करते हैं (जो कि म्यूटेबल हैं, लेकिन इससे इस मामले में कोई फर्क नहीं पड़ता) ऐसा लगता है कि दोनों (अमूर्त) ओ (1) संलग्न करने के साथ अपरिवर्तनीय वैक्टर और ओ (1) इंडेक्सिंग संभव होना चाहिए (ठीक है, यह नहीं है, इस सवाल पर टिप्पणियां देखें)। क्या यह हास्केल में संभव है या मुझे डेटा के साथ जाना चाहिए। सिक्योरेंस जिसमें (AFAICT वैसे भी) ओ (1) संलग्न है और ओ (लॉग (मिनट (i, n-i))) अनुक्रमण?

एक संबंधित नोट पर, हास्केल नौसिखिया के रूप में मुझे खुद को हास्केल डेटा संरचनाओं के लिए एक व्यावहारिक, संक्षिप्त मार्गदर्शिका के लिए उत्सुकता मिलती है। आदर्श रूप से यह सबसे व्यावहारिक डेटा संरचनाओं पर प्रदर्शन विशेषताओं और पॉइंटर्स के साथ हास्केल पुस्तकालयों पर एक व्यापक व्यापक अवलोकन प्रदान करेगा जहां उन्हें कार्यान्वित किया जाता है। ऐसा लगता है कि वहां बहुत सारी जानकारी है, लेकिन मुझे यह थोड़ा बिखरा हुआ है। क्या मेरी मांग बहुत ज़्यादा है?

+0

मुझे पूरा यकीन है कि ऐसी कोई डेटा संरचना मौजूद नहीं है। यदि आपके सभी परिशिष्ट रैखिक रूप से होते हैं, तो 'डेटा.वेक्टर' का उपयोग करें क्योंकि फ़्यूज़न आपको इच्छित प्रदर्शन प्रदान करेगा, अन्यथा 'डेटा.Sequence' –

+0

धन्यवाद का उपयोग करें। मुझे लगता है कि यह संभव होना चाहिए, लेकिन हो सकता है कि विशेष हो ... क्या आप समझा सकते हैं कि 'आपके सभी परिशिष्ट रैखिक रूप से' क्या मतलब है? क्या आपका मतलब रैखिक रूप से बढ़ते सूचकांक के साथ है? ऐसा लगता है कि वेक्टर के साथ प्रत्येक ऑपरेशन अभी भी ओ (एन) ... – Paul

+0

मूल रूप से, यदि आप वेक्टर को अपने कोड के माध्यम से "थ्रेडेड" के रूप में सोच सकते हैं, जो कि मध्यवर्ती मूल्यों को सहेजता नहीं है, तो " एक ही ऑपरेशन में "फ्यूज्ड"। –

उत्तर

9

यदि स्मृति सेवा करता है, तो सी ++ वैक्टर को सीमा और आकार की जानकारी के साथ सरणी के रूप में कार्यान्वित किया जाता है। जब एक सम्मिलन आकार से परे सीमाओं को बढ़ाएगा, तो आकार दोगुना हो जाएगा। यह ओ (1) समय सम्मिलन (ओ (1) जैसा कि आप दावा करते हैं) को अमृत कर दिया गया है, और Array प्रकार का उपयोग करके हास्केल में ठीक लगाया जा सकता है, शायद उपयुक्त IO या ST प्रीपेड के साथ।

+2

शूट करें हां, यह एम (1) को अमूर्त किया गया है, मुझे पता है, इसका उल्लेख करना भूल गया। मैं ऐरे चेकआउट करूंगा, क्या आपके पास आईओ या एसटी के संयोजन के बारे में सीखने के लिए एक अच्छा स्रोत है? अगर कोड संभव हो तो कोड शुद्ध होना पसंद करेंगे और एसटी मोनड के साथ कोई अनुभव नहीं होगा। – Paul

+2

यह कोड शुद्ध नहीं होने वाला है। यह बस संभव नहीं है। अयोग्यता बनाम गैर-उत्परिवर्तन _does_ अंतर बनाते हैं। –

+0

@ पॉल [आलसी कार्यात्मक राज्य थ्रेड] (http://www.cs.fit.edu/~ryan/library/functional_programming/lazy-functional-state-threads.pdf) मूल 'एसटी' पेपर है, मुझे लगता है। –

6

this पर एक नज़र डालें जो आपको उपयोग करना चाहिए इसके बारे में अधिक जानकारी देने के लिए।

लेकिन साधारण बात यह है कि, यदि आप सी ++ वेक्टर के बराबर चाहते हैं, तो Data.Vector का उपयोग करें।

9

सरल ज्ञापन समस्याओं के लिए, आप आम तौर पर एक बार टेबल बनाना चाहते हैं और फिर बाद में इसे संशोधित नहीं करना चाहते हैं। उस स्थिति में, आप एक ऑपरेशन के रूप में ज्ञापन तालिका के निर्माण के बारे में सोचकर, संलग्न करने के बारे में चिंता करने से बच सकते हैं।

एक विधि आलसी मूल्यांकन का लाभ उठाने के लिए है और जब हम इसे बना रहे हैं तो तालिका का संदर्भ लें। जब तालिका के तत्वों के बीच निर्भरता यह मुश्किल उन्हें समय से पहले मूल्यांकन का एक सरल क्रम के साथ आने के लिए बनाता है

import Data.Array 
fibs = listArray (0, n-1) $ 0 : 1 : [fibs!(i-1) + fibs!(i-2) | i <- [2..n-1]] 
    where n = 100 

यह विधि विशेष रूप से उपयोगी है। हालांकि, इसे बॉक्स किए गए सरणी या वैक्टर का उपयोग करने की आवश्यकता है, जो अतिरिक्त ओवरहेड के कारण इस तालिका को बड़ी टेबल के लिए अनुपयुक्त बना सकता है।

अनबॉक्स किए गए वैक्टरों के लिए, आपके पास constructN जैसे ऑपरेशन हैं जो आपको कुशल बनाने के लिए नीचे उत्परिवर्तन का उपयोग करते हुए एक शुद्ध तरीके से एक टेबल बनाने देता है। यह ऐसा कार्य देता है जो आप अब तक बनाए गए वेक्टर के उपसर्ग के एक अपरिवर्तनीय दृश्य को पास करते हैं, जिसे आप अगले तत्व की गणना करने के लिए उपयोग कर सकते हैं।

import Data.Vector.Unboxed as V 
fibs = constructN 100 f 
    where f xs | i < 2 = i 
      | otherwise = xs!(i-1) + xs!(i-2) 
      where i = V.length xs 
+0

वाह, यह 'निर्माण एन' झुका हुआ है। – applicative

+1

मुझे गलत समझा जा सकता है, लेकिन मुझे लगता है कि यह 'Int' के आकार से अधिक होने जा रहा है और डेटा में कोई' अनबॉक्स इंटीजर 'उदाहरण नहीं है। वेक्टर। अनबॉक्सिंग। –

+1

@DougMoore: हाँ, यह बह जाएगा। बिंदु ज्ञापन को चित्रित करना था, फिबोनाची संख्याओं की गणना करने का एक अच्छा तरीका प्रदान नहीं करना। इसके लिए, बहुत बेहतर एल्गोरिदम हैं जिन्हें किसी भी ज्ञापन की आवश्यकता नहीं है :) – hammar

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