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

Arrays 在ocamre中的两个数组之间构造函数的迭代,arrays,function,iteration,ocaml,Arrays,Function,Iteration,Ocaml,我对构造这样的函数有疑问 在这里,我有两个列表,它们都有相同的长度(比如长度是n,我想要的是满足此要求的函数: list1.(0) -> list2.(0) list1.(1) -> list2.(1) ... list1.(n-1) -> list2.(n-1) 如何做?我应该在一个函数内部进行迭代(以及如何进行)?还是附加两个函数(以及如何进行)?必须有一种巧妙的方法来回答这样的问题 很抱歉,我必须自己回答这个问题。我只是发现这其实很简单。我可以很容易地创建一个函数f,它

我对构造这样的函数有疑问

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

list1.(0) -> list2.(0)
list1.(1) -> list2.(1)
...
list1.(n-1) -> list2.(n-1)
如何做?我应该在一个函数内部进行迭代(以及如何进行)?还是附加两个函数(以及如何进行)?必须有一种巧妙的方法来回答这样的问题

很抱歉,我必须自己回答这个问题。我只是发现这其实很简单。我可以很容易地创建一个函数
f
,它是由nlucaroni编写的,要短得多

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

据我所知,您有两个数组。一个定义函数的域,另一个定义范围。您需要编写一个表示此函数的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)

如果您计划在更多的数据集上使用它,那么有一个更好的方法。实际上,对于
映射来说,这是一个糟糕的实现,它有O(n)个查找,而映射则有O(log(n))。我知道您可能对替代方案不感兴趣,因此我将保留我的建议。

如果您知道一个
表达式,请将
匹配
表达式保存到列表和其他数据结构中,这样您就不必使用不安全的函数
List.hd
List.tl
!例如,您的代码rewrites to(ETA:oops,忘记了递归调用):

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

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

你能澄清一下吗?我不明白你想构造什么函数——只是它是在两个长度相等的列表上。要知道列表和数组在OCaml中是完全不同的。@akoprowski:我想做一个函数,如果列表1的第n个参数是输入,我将返回列表2的第n个参数。而且我将在另一个函数中使用此函数作为参数。@nlucaroni:对不起,我是说list,我刚才在那里写了错误的代码,应该是(list.nth 0 list1)->(list.nth 0 list2)等等。
列表
确实改变了我的答案;你应该检查一下
lukstafi
说了什么。非常感谢。我会做一些改变,因为我需要在代码中使用
f
作为参数。我的数据不会太大,所以现在将复杂性从O(n)更改为O(log(n))不会有太大影响。无论如何,O(n)仍然可以处理:)帖子更新!我刚刚意识到,这实际上很容易,因为您正在处理列表。使用
List.combined
List.assc
可能是个好主意。您将生成一个元组('a,'b)来表示这些对。编辑我看到lukstafi几个小时前提到过他们。这绝对是一种更自然的创建关联的方法。@Zfm,很好,这很容易。很高兴有什么必要。
let f domain range =
  let map = List.combine domain range in
  fun x -> List.assoc x map;;