2010-04-25 13 views
8

में किसी सूची से उप सूची कैसे प्राप्त करें I सूची सूची को देख रहा हूं। ऐसा लगता है कि लाइब्रेरी sublist फ़ंक्शन प्रदान नहीं करती है।ओकैम

मैं से से जे से तत्वों की सूची प्राप्त करने का प्रयास कर रहा हूं।

let rec sublist list i j = 
    if i > j then 
    [] 
    else 
    (List.nth list i) :: (sublist list (i+1) j) 

जो काफी संक्षिप्त लेकिन मैं List.nth की दक्षता पर सवाल कर रहा हूँ, क्योंकि अगर यह हे (एन) है, मैं नहीं बल्कि एक कम संक्षिप्त में यह लिखने के लिए होगा: अब मैं इसे लिखने के लिए के रूप में है मार्ग।

मैं सोच रहा हूँ क्यों वे List.sublist समारोह प्रदान नहीं किया, अगर List.nthहे (1) नहीं है, क्योंकि यह इस तरह के एक बहुत आम आपरेशन है ..

उत्तर

9
let rec sublist b e l = 
    match l with 
    [] -> failwith "sublist" 
    | h :: t -> 
    let tail = if e=0 then [] else sublist (b-1) (e-1) t in 
    if b>0 then tail else h :: tail 
;; 

sublist 3 5 [1;2;3;4;5;6;7;8;9] ;; 
- : int list = [4; 5; 6] 

है ऊपर कम या ज्यादा newacct के समाधान का एक कटाई संस्करण है। न्यूएक्ट का समाधान एक इंटरमीडिएट सूची (drop i list) आवंटित करता है, जो संकलक के लिए हास्केल में ऑप्टिमाइज़ करने के लिए संभव है लेकिन एमएल में बहुत कठिन है। इसलिए उनका संस्करण एक हास्केल फ़ंक्शन के लिए बिल्कुल ठीक है और एमएल के लिए मामूली रूप से उप-इष्टतम है। दोनों के बीच का अंतर केवल एक स्थिर कारक है: दोनों ओ (ई) हैं। zrr का संस्करण ओ (लंबाई (एल)) है क्योंकि List.filteri पता नहीं है कि f कुछ समय बाद केवल false लौटाता है, यह इसे l में सभी तत्वों के लिए कॉल करता है।

मुझे b नकारात्मक होने दें और संस्करण जहां यह अधिक जटिल नहीं है, बहुत खुश नहीं है।

वनों की कटाई यदि आप रुचि रखते हैं के लिए काफी कुछ के बीच में एक संदर्भ: http://homepages.inf.ed.ac.uk/wadler/topics/deforestation.html

+1

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

2

यह थोड़ा मुश्किल की तुलना में यह होना चाहिए ओकैमल की मानक लाइब्रेरी के साथ --- मानक लाइब्रेरी थोड़ा सा स्पैस है। यदि आप विस्तारित मानक पुस्तकालयों में से एक का उपयोग करते हैं, तो यह आसान हो जाता है। कोर के साथ, उदाहरण के लिए, आप लिख सकते हैं:

let sublist list low high = 
    List.filteri l ~f:(fun i _ -> i >= low && pos < high) 

मुझे लगता है कि extlib/बैटरी के साथ कुछ ऐसा संभव है।

+2

यह पूरी सूची के माध्यम से जाएगा, भले ही आप सूची की शुरुआत में कुछ चाहते हों। – larsr

5

take (पहले एन आइटम) और drop (सब कुछ लेकिन पहले एन आइटम) कार्यों (जैसे हास्केल में) लिखने का प्रयास करें। तब sublist i j lst सिर्फ take (j-i) (drop i lst)

+0

बैटरियां शामिल या एक्स्ट्लिब जैसी एक्सटेंशन लाइब्रेरी का उपयोग करें और यह आपके लिए ले और ड्रॉप प्रदान करेगा। –

0

पास्कल द्वारा प्रदान की जवाब लागू करता है जबकि List.sublist सही जवाब के लिए एक अच्छी उम्मीदवार है कि आप शायद बेहतर एक सूची की एक सरणी का उपयोग करना चाहिए है । ऐरे मॉड्यूल Array.sub फ़ंक्शन लागू करता है जिसका आप उपयोग कर सकते हैं।

हालांकि ऐसे C++ या पर्ल वहाँ अनिवार्य रूप से सूचियों और सरणियों के बीच कोई अंतर नहीं है कई अनिवार्यता भाषाओं में, इस OCaml में एक ही जहां नहीं है:

  • सूचियाँ बेहतर पुनरावर्ती उपचार और अनुक्रमिक अभिगम के लिए उपयुक्त हैं , यानी आमतौर पर एक रिकर्सिव फ़ंक्शन के लिए तर्क के रूप में एक सरणी के रूप में बेहतर उम्मीदवार होता है, और आप आमतौर पर सूची के सभी तत्वों को देखना चाहते हैं।

  • Arrays यादृच्छिक अभिगम, संरचना परिवर्तन (जैसे सॉर्टिंग), या संख्यात्मक गणना के लिए बेहतर अनुकूल हैं।

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