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

时间:2011-03-08 17:30:54

标签: arrays function iteration ocaml

我对构建这样的函数有疑问。

在这里,我有两个列表,两个都有相同的长度(比如长度为n,我想要的是一个满足这个要求的函数:

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

怎么做?我应该在函数内部进行迭代(以及如何)?或附加两个功能(以及如何)?必须有一些棘手的方法来回答这样的事情。

抱歉,我必须自己回答这个问题。我发现这实际上非常简单。我可以很容易地创建一个由nlucaroni编写的函数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;;

2 个答案:

答案 0 :(得分:2)

据我了解,你有两个阵列。一个定义了函数的域,另一个定义了范围。你想写一个代表这个函数的ocaml函数。我假设这个函数是双射的。缺少的部分,meat,是一个查找数组中元素索引的函数。本着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))。我意识到你可能对替代品不感兴趣,所以我会留下我的建议。

答案 1 :(得分:2)

您知道有一个if表达式,保存列表和其他数据结构的match表达式,这样您就不需要使用不安全函数List.hd和{{1 }}!例如,您的代码重写为(ETA:oops,忘记了递归调用):

List.tl

另一种方法是使用标准库函数:

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;;