【问题标题】:Truncating A List In OCaml在 OCaml 中截断列表
【发布时间】:2023-04-10 06:48:01
【问题描述】:

我是否可以在不使用递归的情况下在 OCaml 中的给定元素之后截断列表?

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

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

【问题讨论】:

  • 这个问题很难搞清楚。 OCaml 中没有 'a queue 类型,也没有任何理由避免使用递归。也无法将任意大小的结构与模式匹配。
  • 类型 'a queue 是 'a list ref?它本质上是一个列表?还有另一种类型的队列,它是一个头尾可变的记录: type 'a queue = { mutable head: 'a qnode option; mutable tail: 'a qnode 选项 }

标签: queue ocaml


【解决方案1】:

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

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

因此,您要查找的函数的类型是

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

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

【讨论】:

  • 如果我想编辑队列而不生成新队列怎么办?到目前为止,这是我的尝试: let rec clear (q: 'a queue): unit = begin match !q with | [] -> () |高清 :: tl -> !q () | hd :: tl -> 如果 hd == elt 然后清除 tl end
【解决方案2】:

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

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

最后一个遍历可变列表并将当前单元格变异为列表的最后一个(如果它包含给定元素)。

【讨论】:

    【解决方案3】:

    你描述的是一种破坏性的数据结构,所以使用可变值和一段时间你可以做到。

    队列接口很好。弹出值,直到找到所需元素:

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

    【讨论】:

      猜你喜欢
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      • 2012-06-02
      相关资源
      最近更新 更多