首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >数组的OCaml压缩元素2乘2

数组的OCaml压缩元素2乘2
EN

Stack Overflow用户
提问于 2016-10-27 18:41:42
回答 2查看 1.1K关注 0票数 1

我需要检查一个数组是否在OCaml中正确排序。

因此,我想分组字符2乘2,然后做一个折叠操作,我比较他们。

不过,我不知道怎么把他们分组。

在Scala中,它看起来如下所示:

代码语言:javascript
运行
复制
val k = Array(1, 2, 3, 4)
k.zip(k.tail)

你知道在OCaml里会是什么样子吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-27 18:49:05

使用Array.init函数,创建一个新数组并将其填充成对,例如.

代码语言:javascript
运行
复制
let zip xs ys = Array.init (Array.length xs) (fun i -> x.(i),y.(i))

但是,我不推荐这种方法。如果您可以轻松地用递归函数表达算法,就没有理由创建中间数据结构。

如果需要比较数组xs和数组ys,那么只需做xs = ys

看起来,您也不希望创建一个由两个数组组成的压缩,而是从数组中提取成对的连续元素,这里是如何使用Array.init实现的。

代码语言:javascript
运行
复制
let zip_with_tail xs = match Array.length xs with
  | 0 | 1 -> [| |]
  | n -> Array.init (n-1) (fun i -> xs.(i),xs.(i+1))

将其与不使用中间数据结构的is_sorted函数进行比较:

let is_sorted xs = let rec ordered i = i = 0 || xs.(i-1) <= xs.(i) && ordered (i-1) in match Array.length xs with | 0 | 1 -> true | n -> ordered (n-1)

样式修饰/处理/取消装饰可以很好地处理懒散序列,在擅长去林的编译器中工作。比如在Haskell。或者用已经很慢的语言,没有必要去费心。我不确定Scala,他们的数组是否懒惰。无论如何,OCaml数组是一个具体的数据结构,OCaml编译器不会优化它(也不应该--数组的语义不允许这样做)。然而,这种编程风格仍然适用于OCaml。您可以使用Core库,它提供了一个名为Sequence的惰性容器。您可以轻松地用同样的方式定义zip_with_tail,就像在Scala中那样:

代码语言:javascript
运行
复制
 let zip_with_tail xs = Sequence.(zip xs (drop xs 1))

下面是一个示例:

代码语言:javascript
运行
复制
# let xs = Sequence.of_list [1;2;3;4;5;6];;
val xs : int Core_kernel.Std.Sequence.t = {1, 2, 3, 4, 5, 6}
# zip_with_tail xs;;
- : (int * int) Core_kernel.Std.Sequence.t =
{(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)}

因此,您可以很好地定义is_sorted

代码语言:javascript
运行
复制
let is_sorted xs = zip_with_tail xs |>
                   Sequence.for_all ~f:(fun (x,y) -> x <= y)

这里,zip_with_tail xs不会创建一个中间数组,它实际上具有O(1)复杂性。在引擎盖下面,它将返回一个函数,它将生成元素。Sequence.for_all将检查它们是否都已排序。

票数 3
EN

Stack Overflow用户

发布于 2016-10-27 19:04:12

这将使数组成为一对相邻元素的列表:

代码语言:javascript
运行
复制
let a2pairs a =
    let mkpr x (prevo, prs) =
        match prevo with
        | None -> (Some x, [])
        | Some y -> (Some x, (x, y) :: prs)
    in
    snd (Array.fold_right mkpr a (None, []))

它的工作方式如下:

代码语言:javascript
运行
复制
# a2pairs [| 1;2;3;4 |];;
- : (int * int) list = [(1, 2); (2, 3); (3, 4)]

但我同意@ivg的观点,即创建这种中间数据结构可能不值得。您可以使用几乎相同的函数来比较相邻的元素,并积累一个布尔值,以说明它们是否都是正确的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40291948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档