【问题标题】:Last occurence of element in a list in OCamlOCaml 列表中最后出现的元素
【发布时间】:2010-12-06 01:55:08
【问题描述】:

假设l 是一个列表并且elem 是一个元素,我如何返回元素elem 在列表l 中的最后一次出现?如果元素在 l 中不存在,也返回 -1。我不太明白如何使用递归来遍历列表...

let rec getLastOccurence l elem = …

【问题讨论】:

  • 您是指最后一次出现的“索引”吗?因为否则返回值(元素和-1)不是同一类型

标签: list recursion ocaml


【解决方案1】:

这是在列表中查找整数的尾递归算法:

let find_index elt lst =
  (* Wrap inner function that accepts an accumulator to keep the interface clean *)
  let rec find_it elt acc = function
    | hd :: tl when elt = hd -> acc (* match *)
    | hd :: tl -> find_it elt (acc + 1) tl (* non-match *)
    | _ -> raise Not_found (* end of list *)
  in find_it elt 0 lst (* call inner function with accumulator starting at 0 *)
;;

【讨论】:

  • 我听不懂这行 | _ -> 提高 Not_found
  • 前两个匹配选项使用 cons 运算符 (::) 捕获存在头部和尾部元素的情况。 _ 符号是一个约定俗成的说法,“忽略此匹配”。该模式匹配任何内容,但由于前两个捕获从 a :: b 到 a :: nothing 的所有内容,因此最后一个用于捕获我们遍历整个列表但未找到匹配项的情况。重新阅读您的问题,您想将“raise Not_found”更改为-1。
  • 请注意,您也可以使用“| [] -> raise Not_found”作为最终模式。两者都不会绑定到变量。它们实际上是等效的。
  • 这将找到第一个索引。 Polly 似乎正在寻找最后一个索引。虽然您可以在 (List.rev lst) 上执行此操作以获取列表末尾的偏移量。
  • 啊,她想要最后一次。不仔细阅读作业的自我downmod :)
【解决方案2】:
let findi x l = 
  let rec loop i n l = 
    match l with 
    | y::tl -> loop (i+1) (if y = x then i else n) tl 
    | [] -> n 
  in 
  loop 0 (-1) l;;

【讨论】:

    【解决方案3】:

    基本上,您需要两个累加器来跟踪当前索引和为元素找到的最大索引。然后你只需递归到列表的末尾并返回“最大索引”值。

    let rindex elem = 
      let rec find_index i max_found = function
        | (x::xs) when x = elem -> find_index (i+1) i xs
        | (_::xs) -> find_index (i+1) max_found xs
        | [] -> max_found
      in find_index 0 (-1);;
    

    这也可以很简单地表示为折叠:

    let rindex elem ls = 
      let find_index (i, max) elem' = (i+1, if elem' = elem then i else max)
      in snd (fold_left find_index (0, -1) ls);;
    

    【讨论】:

      猜你喜欢
      • 2013-09-13
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多