2014-10-27 80 views
1

我有以下問題。從列表中,我必須將mod 3 = 0元素,mod 3 = 1元素和mod 3 = 2元素分隔爲3個不同的列表並返回這3個列表的列表。我的問題很明顯 - 我該怎麼做?有沒有這種我錯過的簡單規則?OCaml - 如何從列表中返回列表清單?

我至今並不多,但你去:

let separate xs = 
    let rec help xs i = 
    match xs i with 
    | [] _ -> [] 
    | hd a -> if a mod 3 = 0 //HOW DO I RETURN 
         else if a mod 3 = 1 
         else 

更新: 成品代碼:

let separate xs = 
let rec help (list, i, xs1, xs2, xs3) = 
    match list with 
    | [] -> [xs1;xs2;xs3] 
    | head :: tail -> (if i mod 3 = 0 then help (tail, i+1, head::xs1, xs2, xs3) 
             else if i mod 3 = 1 then help (tail, i+1, xs1, head::xs2, xs3) 
             else help (tail, i+1, xs1, xs2, head::xs3)) 
in help (xs, 0, [], [], []);; 
+0

你能告訴我們你到目前爲止有什麼? – Marth 2014-10-27 11:00:45

+0

我有點卡在一開始,因爲我不知道我該如何寫東西才能返回,但是肯定 - 在原評論中 – 2014-10-27 11:01:59

回答

2

你需要積累在列表中的部分結果,並然後返回這些列表:

let split_by_mod_3 l = 
    let rec aux l mod0 mod1 mod2 = match l with 
    | [] -> [mod0; mod1; mod2] 
    | hd::tail when hd mod 3 == 0 -> aux tail (hd::mod0) mod1 mod2 
    | hd::tail when hd mod 3 == 1 -> aux tail mod0 (hd::mod1) mod2 
    | hd::tail when hd mod 3 == 2 -> aux tail mod0 mod1 (hd::mod2) 
    in 
    aux l [] [] [];; 
+1

謝謝了,雖然我不能使用「when」關鍵字,感謝您的代碼,我明白了規則。用我的代碼更新了我的原始問題。 – 2014-10-27 11:58:52

1

通常的方法是使用List.fold*函數,它概括了列表迭代的思想。但是,就你而言,這可能不合適(取決於你的老師的要求)。

你可以迭代你的列表,保持一些狀態的概念(事實上,你需要三個額外的「變量」爲三個不同的列表)。這是一個迭代列表的模式

let my_function lst = 
    let rec loop acc lst = match lst with 
    | [] -> <do_some_post_iteration_work> acc 
    | head :: rest -> 
     let result = <do_something_with_nth_element> head in 
     let accum = <add_result_to_accumulator> result acc in 
     loop accum rest in 
    let accum = <initialize_accumulator> in 
    loop accum lst 

我用了很長的名字,以便您可以理解沒有額外註釋的意思,儘管歡迎您提問。另外,請記住,你的狀態(又名累加器)也可以是任何類型的值。在你的情況下使用三元組是一個不錯的主意。