截断OCaml中的列表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了截断OCaml中的列表相关的知识,希望对你有一定的参考价值。

我是否有可能在OCaml中的给定元素之后截断列表而不使用递归?

let truncate (elt: 'a) (q: 'a queue) : unit =

我可以想到如何使用嵌套模式匹配来实现这一点...寻找一种没有rec的更好方法

答案

列表节点包含所有下一个元素。

因此,要截断列表,您需要创建一个仅包含第一个元素的新列表(这是获取所需截断列表的唯一方法)。

因此,您正在寻找的函数类型是

let truncate : 'a -> 'a list -> 'a list 
= fun elt queue -> ...

正如Jeffrey Scofield所说,避免递归是没有意义的。

另一答案

当然,如果你真的想,你可以做很多事情。有两个技术避免递归的例子,然后我认为你可能实际上一直在寻找:

let truncate1 elt list = (* tedious iteration version *)
  let list = ref list in
  let r = ref [] in
  while !list <> [] do
    r := List.hd !list :: !r;
    if List.hd !list = elt then list := [] else
      list := List.tl !list
  done;
  List.rev !r

let truncate2 elt list = (* let's not mind how List.find does it version *)
  let r = ref [] in
  ignore (List.find (fun x -> r := x :: !r; x = elt) list);
  List.rev !r

(* this is more what you're looking for? version *)
type 'a mutcons = { mutable head : 'a; mutable tail : 'a mutlist }
and 'a mutlist = Nil | Cons of 'a mutcons

let rec mutlist_iter f = function
  | Nil -> ()
  | Cons k -> f k; mutlist_iter f k.tail

let rec truncate3 elt mlist =
  mutlist_iter (fun k -> if k.head = elt then k.tail <- Nil) mlist

最后遍历可变列表的位置,如果当前单元格包含给定元素,则将当前单元格变为最后一个列表。

另一答案

你描述的是一个破坏性的数据结构,所以有了可变的值,你可以做一段时间。

队列接口是好的。弹出值,直到找到欲望元素:

Pseudo alorithm
Do 
    Current = queue.pop myqueue
Until (current = desiredvalue) or (queue.isempty myqueue)

 Return myqueue

以上是关于截断OCaml中的列表的主要内容,如果未能解决你的问题,请参考以下文章

OCaml和OCaml评估模型中的功能应用列表

访问 ocaml 中的全局参考列表 [关闭]

将哈希表转换为 OCaml 中的对列表(键、值)

在 OCaml 中访问 (int * float) 列表中的浮点数

如何使用 OCaml 将两个列表中的每个单独元素压缩到一个列表中

OCaml 中的 D 类不可变数据切片