【问题标题】:Trying to add an element to front of doubly-linked list ocaml试图在双向链表 ocaml 前面添加一个元素
【发布时间】:2019-10-17 03:00:21
【问题描述】:

我正在尝试将一个元素添加到双向链表的前面,但是,我得到了正确的输出形式,但循环节点的值显示:{content = < cycle >},而它应该只是说@ 987654322@.

add_head: (float * 'a) -> ('a lcell) ref -> unit
(* The type of linked lists. *)
type 'a llist =
| Nil
| Cons of (float * 'a) * 'a lcell * 'a lcell
and 'a lcell = ('a llist) ref

let add_head x head = 
   match !(!head) with
   |Nil -> head := !(singleton x)
   |Cons (e, prev, next) -> 
      let first = ref (Cons (x, ref Nil, ref !(!head))) in
      prev := !first;
      head := first   

这是输出的样子:

  {contents =
    Cons ((3.3, "c"), {contents = Nil},
     {contents =
       Cons ((1.2, "b"), <cycle>,
        {contents = Cons ((2.2, "a"),<cycle>, {contents = Nil})})})}}

这是我的输出:

  {contents =
    Cons ((3.3, "c"), {contents = Nil},
     {contents =
       Cons ((1.2, "b"), {contents =<cycle>},
        {contents = Cons ((2.2, "a"), {contents =<cycle>}, {contents = Nil})})})}}

对于为什么会发生这种情况以及我不理解的任何帮助?

【问题讨论】:

  • 你的字体是什么样的?添加元素的代码在哪里?您尝试了什么可以提供上述数据?
  • 请不要破坏您自己的问题。如果您不希望在此处使用您的代码,那么您一开始就不应该发布它。

标签: linked-list ocaml doubly-linked-list


【解决方案1】:

当你写作时

      let first = ref (Cons (x, ref Nil, ref !(!head))) in

您正在为 first 创建一个新的参考,因此它不能出现在列表的后面。 然后,当你用

更新prev
      prev := !first;

您正在使prev 指向新引用的内容。最后, prev 指向一个循环,但它不是循环的一部分。

如果你想避免这种间接,你需要重用已经存在的prev 引用而不是创建一个新的引用:

let add_head x head = 
   match !(!head) with
   | Nil -> head := !(singleton x)
   | Cons (e, prev, next) -> 
      let first = Cons (x, ref Nil, !head) in
      prev := first;
      head := prev;;   

那么你应该得到:

# let r= ref (ref Nil);;
# add_head (0., 0) r;;
# add_head (1., 1) r;;
# add_head (2., 2) r;;
# !r;;
{contents =
  Cons ((2., 2), {contents = Nil},
   {contents =
     Cons ((1., 1), <cycle>,
      {contents = Cons ((0., 0), <cycle>, {contents = Nil})})})}

【讨论】:

    【解决方案2】:

    这是我对这个问题的看法。

    在您的函数中,head 是对单元格的引用。该函数应该更新单元格,而不是对单元格的引用。因此,当您分配给要执行此操作的头部时:

    !head := <new value>
    

    不是这个:

    head := ref (<new value>)
    

    我写了一些遵循这种模式的代码,它得到了你说的正确答案。

    (这与在 C 中获取 * 取消引用的数量完全相同。这也是函数式代码更令人愉悦的原因之一 :-)

    【讨论】:

    • 嗨,Jeffrey,我对代码的最后一行进行了您所说的更改,但现在出现类型错误。所以我尝试通过 !head := !first 来修复它,但这给了我和以前一样的答案。您能否详细说明您所做的更改?谢谢
    猜你喜欢
    • 2017-03-05
    • 2017-02-25
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多