2011-03-08 42 views
2

我有關於構建一個像這樣的函數的問題。迭代在ocamlre中構造兩個數組之間的函數

在這裏,我有兩個表,都具有相同的長度(說長度爲n,那我想情況是滿足這一需求的功能:

list1.(0) -> list2.(0) 
list1.(1) -> list2.(1) 
... 
list1.(n-1) -> list2.(n-1) 

怎麼辦呢?我應該做一個函數內部的迭代嗎?或者如何追加兩個函數(以及如何)?必須有棘手的方法來回答這樣的問題

對不起,必須自己回答這個問題,我只是發現這個其實很簡單,我可以很容易地創建一個函數f,這個函數寫得非常簡短。

let rec f domain range x = 
match (List.hd domain) = x with 
    | true -> (List.hd range) 
    | false -> f (List.tl domain) (List.tl range) x;; 
+0

你可以嘗試澄清?我不明白你想要構建什麼功能 - 只是它有兩個相同長度的列表。 – akoprowski 2011-03-08 18:18:51

+0

意識到OCaml中的列表和數組完全不同。 – nlucaroni 2011-03-08 21:09:01

+0

@akoprowski:我想創建一個函數,其中如果list1的第n個參數是輸入,我將返回list2的第n個參數。此外,我將使用這個函數作爲另一個函數的參數。 – zfm 2011-03-08 22:01:48

回答

2

從我的理解,你有兩個數組。一個定義了函數的範圍,另一個範圍。你想寫一個代表這個函數的ocaml函數。我在這裏假設函數是雙射的。缺少的部分肉是一個函數,用於查找數組中元素的索引。本着List.find的精神,我決定通過一個函數來定義這個比較。

let find_index p array = 
    let rec find_index idx = 
     if idx = (Array.length array) then raise Not_found 
     else if (p array.(idx)) then idx 
     else find_index (idx+1) 
    in 
    find_index 0 

從這裏是微不足道的創造功能,其逆,

let f domain range x = range.(find_index (fun y -> 0 = compare x y) domain) 
let f' domain range y = domain.(find_index (fun x -> 0 = compare x y) range) 

有一個更好的方式,如果你打算使用此上更多的則只是一個小的數據集。實際上,對於Map這是一個糟糕的實現 - 這有O(n)查找,而映射將有O(log(N))。我意識到你可能不會對替代品感興趣,所以我會留下我的建議。

+0

非常感謝。由於我需要在我的代碼中使用f作爲參數,因此我會稍微改變一下。 – zfm 2011-03-08 20:43:32

+0

我的數據不會那麼大,所以從O(n)到O(log(n))的複雜度現在不會太大影響。在任何情況下,O(n)仍然易於處理:) – zfm 2011-03-08 22:46:33

+0

發佈更新!我只是意識到這實際上很容易 – zfm 2011-03-08 23:46:14

2

有你知道的if表達,保存列表等數據結構match表達,這樣你就不需要使用不安全的功能List.hdList.tl!例如你的代碼重寫爲(ETA:哎呀,忘了遞歸調用):

let rec f domain range x = 
match domain, range with 
    | k::_, v::_ when k = x -> v 
    | _::ks, _::vs -> f ks vs x 
    | _ -> raise Not_found;; 

另一種方法是使用標準庫函數:

let f domain range = 
    let map = List.combine domain range in 
    fun x -> List.assoc x map;; 
相關問題