2013-11-27 5 views
6
let rec mem list x = match list with 
       | [] -> false 
       | head :: tail -> 
        if x = list.Head 
        then true 
        else mem list.Tail x 

फ़ंक्शन मेम एक सूची और एक var एक्स को पैरामीटर के रूप में लेता है और जांच करता है कि सूची में मान X है और यदि यह करता है और गलत होता है तो सत्य लौटाता है।f # सूचियों का छेड़छाड़

let rec intersection list1 list2 = match list1 with 
       | head :: tail -> match list2 with 
        | head :: tail -> if mem list2 list1.Head = true 
        then (*add the value to a list*) else intersection list1.Tail list2 
       | [] -> failwith "Second list is empty" 
     | [] -> failwith "First list is empty" 

मैं काफी एफ # और समस्या मैं अभी कर रहा हूँ मुझे नहीं पता है कि (एक सूची को जोड़ने के मूल्य ) में एक सूची का निर्माण और फिर इसे करने के लिए मूल्य जोड़ने के लिए है करने के लिए नया हूँ। मैंने अभी तक कोड का परीक्षण किया है क्योंकि मुझे त्रुटियों को प्राप्त करने के लिए पहले इस चरण को पूरा करने की आवश्यकता नहीं है, इसलिए यह 100% सुनिश्चित नहीं है कि यह कैसे काम करता है।

मैं 2 सूचियों को छेड़छाड़ करने की कोशिश कर रहा हूं, मुझे पता है कि यह "Set.Intersect list1 list2" के लिए कार्य मौजूद है। इंडेंटेशन थोड़ा अजीब है क्योंकि यहां तक ​​कि मैं पंक्तियों तक नहीं पहुंचना चाहता था लेकिन आप शायद वैसे भी समझेंगे।

उत्तर

6

अपने कोड को ठीक करने का सबसे सीधा तरीका नीचे दिए गए कोड की तरह कुछ लिखना है।

mem समारोह में, मैं सिर्फ खरोज तय की और head और tail कि आप मिलान पैटर्न के बजाय list.Head और list.Tail के माध्यम से उन्हें एक्सेस करने से मिलता है का उपयोग करने के लिए इसे बदल (क्योंकि है कि और अधिक मुहावरेदार और सुरक्षित है कर रही है):

let rec mem list x = 
    match list with 
    | [] -> false 
    | head :: tail -> 
    if x = head then true else mem tail x 

intersection में, चाल head::rest उपयोग करने के लिए एक सूची बनाने के लिए जिसके परिणामस्वरूप जब head एक तत्व है कि दोनों सूचियों में प्रकट होता है (और rest सूची है कि आप पुनरावर्ती पूंछ के चौराहे लगाने से मिलता है) है। ,

let rec intersection list1 list2 = 
    match list1 with 
    | head :: tail -> 
     let rest = intersection tail list2 
     if mem list2 head then head::rest 
     else rest 
    | [] -> [] 

इस सुपर कुशल (यह मानते हुए nlist1 और मीटर की लंबाई है नहीं है list2 की लंबाई है आप कर सकते हैं: आप भी क्योंकि mem खाली सूचियों ठीक संभालती list2 पर मैच के लिए की जरूरत नहीं है एम * एन चरणों की आवश्यकता है), लेकिन शायद यह बिंदु नहीं है। इसके अलावा, intersection पूंछ-पुनरावर्ती नहीं है, इसलिए यह बड़ी सूचियों पर काम नहीं करेगा, लेकिन यह एक और अधिक उन्नत - कार्यात्मक प्रोग्रामिंग विषय है।

अंत में, कोड भी वापस आ जाएगी सूची एक भी तत्व कई बार हो सकती है कि - लेकिन मुझे लगता है कि यह है कि आप के लिए ठीक है (उदाहरण के लिए intersection [1;1;1] [1][1;1;1] रिटर्न लेकिन अगर आप तर्क फ्लिप तुम सिर्फ [1] मिल जाएगा)

1

ऐसा करने के लिए आपको बनाई जा रही सूची का ट्रैक रखने की आवश्यकता होगी। यह करने के लिए सबसे अच्छा तरीका है एक सहायक समारोह है कि एक पैरामीटर के रूप में बनाया जा रहा सूची लेता है और पुनरावर्ती कॉल

let intersection list1 list2 = 
    let rec inner list1 list2 builtList = 
    match list1 with 
    | head :: tail -> 
     match list2 with 
     | head :: tail -> 
     if mem list2 list1.Head = true then 
      inner tail list2 (list1.Head :: builtList) 
     else 
      inner tail list2 builtList 
     | [] -> failwith "Second list is empty" 
    | [] -> failwith "First list is empty" 
    inner list1 list2 [] 

एक अन्य टिप्पणी है कि एक खाली सूची पर विफल रहने के खराब व्यवहार का है में यह निर्धारित करने के लिए है। बस कोई तत्वों के साथ एक सूची के रूप खाली सूची का इलाज इसलिए कोई चौराहे संभव

let intersection list1 list2 = 
    let rec inner list1 list2 builtList = 
    match list1 with 
    | head :: tail -> 
     if mem list2 list1.Head = true then 
     inner tail list2 (list1.Head :: builtList) 
     else 
     inner tail list2 builtList 
    | [] -> builtList 

    inner list1 list2 [] 

इस संस्करण में काम करता है है, लेकिन एक सूची उलटे क्रम है कि वे list1 में प्रदर्शित में तत्व है कि लौटने खत्म हो जाएगा।ठीक करने के लिए है कि हम एक कॉलबैक का उपयोग कर सकते सही क्रम

let intersection list1 list2 = 
    let rec inner list1 list2 builder = 
    match list1 with 
    | head :: tail -> 
     if mem list2 list1.Head = true then 
     inner tail list2 (fun next -> list1.Head :: next) 
     else 
     inner tail list2 builder 
    | [] -> (builder []) 

    inner list1 list2 (fun x -> x) 
8

मैं सेट ऑपरेटरों का उपयोग करना चाहते में सूची का निर्माण करने के http://msdn.microsoft.com/en-us/library/ee353629.aspx आप Set.intersect (Set.ofList list1) (Set.ofList list2) |> Set.toList

उपयोग कर सकते हैं