迭代在ocamlre中构造两个数组之间的函数

问题描述:

我有关于构建一个像这样的函数的问题。迭代在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

从我的理解,你有两个数组。一个定义了函数的范围,另一个范围。你想写一个代表这个函数的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

有你知道的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;;