स्काला में सूची में हे (एन) समय जटिलता के लिए अपील क्यों करता है?


13

मैंने अभी पढ़ा कि a List: (: +) के लिए परिशिष्ट ऑपरेशन का निष्पादन समय आकार के साथ रैखिक रूप से बढ़ता है List

Listएक बहुत ही आम ऑपरेशन की तरह लग रहा है । ऐसा करने के लिए मुहावरेदार तरीका क्यों होना चाहिए कि वे घटकों को पूर्वनिर्मित कर सकें और फिर सूची को उलट सकें? यह एक डिज़ाइन विफलता भी हो सकती है क्योंकि कार्यान्वयन को किसी भी बिंदु पर बदला जा सकता है।

मेरे दृष्टिकोण से, पूर्ववर्ती और संलग्न दोनों O (1) होने चाहिए।

क्या इसका कोई वाजिब कारण है?


2
"वैध" की आपकी परिभाषा पर निर्भर करता है। स्केला भारी डेटा संरचनाओं, सर्वव्यापी अनाम सूचियों, कार्यात्मक रचना, आदि में भारी है। डिफ़ॉल्ट सूची कार्यान्वयन (सूची पूंछ के लिए एक अतिरिक्त परस्पर सूचक के बिना) उस शैली के लिए अच्छी तरह से काम करता है। यदि आपको अधिक शक्तिशाली सूची की आवश्यकता है, तो कम से कम अपने कंटेनर को लिखना बहुत आसान है जो मानक लोगों से लगभग अप्रभेद्य है।
किलियन फोथ

1
क्रॉस साइट संबंधित - स्कैला में किसी सूची के अंत में एक तत्व को जोड़ना - वहां की प्रकृति के बारे में कुछ सा है। ऐसा प्रतीत होता है कि स्केला में एक सूची अपरिवर्तनीय है, इस प्रकार आपको इसे कॉपी करने की आवश्यकता है, जो ओ (एन) है।

आप कई उपलब्ध उत्परिवर्तनीय डेटा संरचनाओं में से एक का उपयोग कर सकते हैं, या ओ (1) परिशिष्ट समय (वेक्टर) के साथ अपरिवर्तनीय डेटा संरचनाओं का उपयोग कर सकते हैं जो स्काला प्रदान करता है। List[T]मान लें कि आप इसका उपयोग उस तरह से कर रहे हैं जैसे आप एक शुद्ध कार्यात्मक भाषा में करते हैं - आम तौर पर सिर से डिकंस्ट्रक्शन और प्रीपेंड्स के साथ काम करना।
KChaloux

3
प्रीपेंडिंग नए हेड के अगले नोड पॉइंटर को मौजूदा अपरिवर्तनीय सूची में डाल देगा - जो बदल नहीं सकता है। Thats O (1)।

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

जवाबों:


24

मैं अपनी टिप्पणी को थोड़ा विस्तार दूंगा। List[T]डेटा संरचना, से scala.collection.immutableएक अधिक विशुद्ध रूप से कार्यात्मक प्रोग्रामिंग भाषा पर काम चल रहा अपरिवर्तनीय सूची तरह से काम करने के लिए अनुकूलित है। यह बहुत तेजी से किया गया है पहले जोड़ें बार, और यह माना जाता है कि आप अपनी पहुंच के लगभग सभी के लिए सिर पर काम करेंगे।

अपरिवर्तनीय सूचियाँ इस तथ्य के कारण बहुत तेज़ गति से प्राप्त होती हैं कि वे "लिप्त कोशिकाओं" की एक श्रृंखला के रूप में अपनी जुड़ी हुई सूचियों को मॉडल करती हैं। सेल एक एकल मान को परिभाषित करता है, और अगली सेल को एक सूचक (क्लासिक एकल-लिंक्ड-सूची शैली):

Cell [Value| -> Nil]

जब आप किसी सूची में जाते हैं, तो आप वास्तव में केवल एक नया सेल बना रहे होते हैं, शेष मौजूदा सूची के साथ:

Cell [NewValue| -> [Cell[Value| -> Nil]]

क्योंकि सूची अपरिवर्तनीय है, आप बिना किसी वास्तविक प्रतिलिपि के ऐसा करने के लिए सुरक्षित हैं । पुरानी सूची के बदलने और आपकी नई सूची के सभी मूल्यों को अमान्य बनाने का कोई खतरा नहीं है। हालाँकि, आप एक समझौता के रूप में अपनी सूची के अंत तक एक परस्पर सूचक रखने की क्षमता खो देते हैं ।

यह सूचियों पर पुनरावर्ती रूप से काम करने के लिए बहुत अच्छी तरह से उधार देता है। मान लीजिए कि आपने अपना स्वयं का संस्करण परिभाषित किया है filter:

def deleteIf[T](list : List[T])(f : T => Boolean): List[T] = list match {
  case Nil => Nil
  case (x::xs) => f(x) match {
    case true => deleteIf(xs)(f)
    case false => x :: deleteIf(xs)(f)
  }
}

यह एक पुनरावर्ती कार्य है जो विशेष रूप से सूची के प्रमुख से काम करता है, और :: चिमटा के माध्यम से मिलान पैटर्न का लाभ उठाता है। यह कुछ ऐसा है जिसे आप हास्केल जैसी भाषाओं में देखते हैं।

यदि आप वास्तव में तेजी से अपील चाहते हैं, तो स्काला चुनने के लिए बहुत से उत्परिवर्तनीय और अपरिवर्तनीय डेटा संरचनाएं प्रदान करता है। परिवर्तनशील पक्ष पर, आप गौर कर सकते हैं ListBuffer। वैकल्पिक रूप से, Vectorसे scala.collection.immutableएक तेजी से संलग्न समय है।


अब मुझे समझ आई! यह पूर्ण समझ में आता है।
DPM

मैं किसी भी स्काला को नहीं जानता, लेकिन क्या वह elseअनंत लूप नहीं है ? मुझे लगता है कि यह कुछ ऐसा होना चाहिए x::deleteIf(xs)(f)
18

@svick उह ... हाँ। हाँ यही है। मैंने इसे जल्दी से लिखा और अपने कोड को सत्यापित नहीं किया, क्योंकि मेरे पास जाने के लिए एक बैठक थी: p (अब ठीक किया जाना चाहिए!)
KChaloux

@Jubbat क्योंकि headऔर tailसूची इस तरह से पहुँच बहुत तेजी से है - तेजी से किसी भी हैश आधारित नक्शा या सरणी का उपयोग करने से - यह पुनरावर्ती कार्यों के लिए एक उत्कृष्ट प्रकार है। यह एक कारण है कि सूची में सबसे कार्यात्मक भाषाओं (जैसे हास्केल या योजना) में एक कोर प्रकार हैं
itsbruce

बहुत बढ़िया जवाब। मैं शायद एक TL जोड़ूंगा; DR जो बस कहता है "क्योंकि आपको प्रीपेड होना चाहिए, न कि एपेंडिंग" (आधार डेवलपर्स को स्पष्ट करने में मदद मिल सकती है List
डैनियल बी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.