2011-09-11 7 views
19

में किसी सूची का अंतिम तत्व प्राप्त करने का सबसे तेज़ तरीका हैस्केल में किसी सूची का अंतिम तत्व प्राप्त करने का सबसे तेज़ तरीका क्या है। इसके अलावा अगले पुनरावृत्ति में, मैं सूची के पहले और अंतिम तत्व को हटाना चाहता हूं। ऐसा करने का सबसे शानदार तरीका क्या है? मैं सूची समझने की कोशिश कर रहा हूं, लेकिन यह बहुत कुशल नहीं दिख रहा है!हास्केल

+3

मैं पुन: प्राप्त करने लगता है * पिछले * तत्व कुशलता से मुश्किल है। हो सकता है कि आपको संदर्भ को अधिक विस्तार से समझाएं, इसलिए कोई यह देख सकता है कि आपकी डेटा आवश्यकताओं के अनुरूप अन्य डेटा संरचनाएं हो सकती हैं या नहीं। – phimuemue

+1

इस बात पर संदेह करने का कोई कारण नहीं है कि Prelude.last का अच्छा कार्यान्वयन है। बेहतर प्रश्न, जैसा कि फिमुम्यू कहते हैं, यह है कि, यदि आप 'आखिरी' का उपयोग कर रहे हैं तो आपको सूचियों के अलावा कुछ और की आवश्यकता नहीं है, उदा। डेटा। पर्याप्तता या उस तरह का कुछ। – applicative

उत्तर

32

last और init नौकरी के लिए बस ठीक काम करेगा। हालांकि वे ओ (एन) दोनों हैं, इसलिए यदि आपको लगता है कि आप अक्सर सूची के दोनों सिरों में हेरफेर करना चाहते हैं, तो आप Data.Sequence का उपयोग करने पर विचार करना चाहेंगे, जो ओ (1) सम्मिलन और निष्कासन का समर्थन करता है दोनों सिरों पर वस्तुओं का।

listLast :: [a] -> a 
listLast [x] = x --base case is when there's just one element remaining 
listLast (_:xs) = listLast xs --if there's anything in the head, continue until there's one element left 
listLast [] = error "Can't do last of an empty list!" 

ध्यान दें कि मैं listLast को समारोह का नाम बदल दिया है ताकि यह सामान्य प्रस्तावना के साथ परस्पर विरोधी बिना चलाया जा सकता है:

67

आप सूची के अंतिम तत्व प्राप्त करने के लिए the last function का उपयोग कर सकते हैं।

पहले और अंतिम तत्वों को हटाने के तरीके के रूप में, आप (init . tail) का उपयोग कर सकते हैं, लेकिन मुझे नहीं पता कि यह कितना कुशल है।

मुझे लगता है कि Learn You A Haskell से इस छवि को सूची कार्यों काफी अच्छी तरह से पता चलता है:

illustration of list functions

+0

'(init। पूंछ) 'गलत/मिसाइलिंग नहीं है? यह '(सिर पूंछ) होना चाहिए। – nulvinge

+1

@ नूलविंग (सिर पूंछ) सूची में दूसरा तत्व वापस कर देगा। उपरोक्त तस्वीर देखें :) – Phyx

+0

ओपीएस, क्षमा करें, आप सही हैं। हाल ही में पहचानने के लिए बहुत सी योजना में किया जा रहा है। रचना के रूप में ... – nulvinge

0

निकालने के लिए पहली और आखिरी:

take (len(l)-2) (drop 1 l) 

या शायद

init (drop 1 l) 

यह भी परिणाम लगभग इष्टतम कोड में परिणाम।

5

मैं प्रस्तावना कार्यान्वयन पोस्ट करेंगे, क्योंकि यह अभी तक नहीं दिया गया है। आप निश्चित रूप से import Prelude hiding(last) कर सकते हैं।

+0

इस http://learnyouahaskell.com/chapters में वह जिस सम्मेलन का उपयोग करती है वह 'आखिरी' – CSharper

-2
(head.reverse) [1..100] 

अंतिम तत्व प्राप्त करने के लिए last का विकल्प है।

drop 1 (take (length [1..100] - 1) [1..100]) 

पहला और अंतिम सूची तत्व हटा देता है। drop और take के लिए स्रोत यह दिखता है कि यह (init . tail) से अधिक तेज हो सकता है।

(reverse.drop 1) ((reverse.drop 1) [1..100]) 

एक और संस्करण है। लेकिन मुझे डबल रिवर्सल की वजह से धीमा लगता है।

+1

'लंबाई' शायद ही कभी किसी अच्छे कारण के बिना करना चाहती है। यहां कोई अच्छा कारण नहीं है। वही 'रिवर्स' के लिए जाता है। – dfeuer

0

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

निम्नलिखित के लिए, आप

import Control.Monad ((>=>)) 

की आवश्यकता होगी और आप या तो GHC 7 उपयोग करने के लिए की आवश्यकता होगी।

init' :: [x] -> Maybe [x] 
init' = foldr go Nothing 
    where 
    go x mxs = Just (maybe [] (x:) mxs) 

tail का एक संस्करण लिखा जा सकता है

tail' :: [a] -> Maybe [a] 
tail' = fmap snd . uncons 

तो फिर आप प्राप्त कर सकते हैं: 10 और आयात Data.List (uncons) या

uncons :: [a] -> Maybe (a, [a]) 
uncons [] = Nothing 
uncons (x:xs) = Just (x,xs) 

परिभाषित आप इस तरह init का एक सुरक्षित रूप में लिख सकते हैं एक शायद

trim' :: [a] -> Maybe [a] 
trim' = init' >=> tail' 

>=> पिछड़ा monadic संरचना का एक प्रकार है। init' >=> tail' एक ऐसा फ़ंक्शन है जो Maybe [a] प्राप्त करने के लिए init' पर लागू होता है। अगर यह Nothing प्राप्त करता है, तो वह इसे वापस कर देता है। यदि यह Just xs प्राप्त करता है, तो यह tail' पर xs पर लागू होता है और उसे वापस करता है।

इस से, आप आसानी खाली सूचियों के लिए नीचे एक ट्रिमर कि 0, 1, या 2 तत्वों के साथ सूचियों ट्रिम कर सकते हैं:

trim :: [a] -> [a] 
trim = maybe [] id . trim'