繁体   English   中英

OCaml。 返回列表的前n个元素

[英]OCaml. Return first n elements of a list

我是OCaml和整个函数编程的新手。 我正在分配的一部分中,我必须简单地返回列表的前n个元素。 我不允许使用List.Length。

我觉得我所写的内容可能过于复杂。 我的代码尝试执行的操作是将列表的开头连接到末尾,直到n减小到1。此时,头将n-1点再移动到列表的末尾,然后返回该尾部。 再一次,我意识到可能有一种更简单的方法来执行此操作,但是我很沮丧,并且可能显示出我无法掌握函数式编程。

   let rec take n l =
        let stopNum = 0 - (n - 1) in
        let rec subList n lst =
        match lst with
        | hd::tl -> if n = stopNum then (tl)
                        else if (0 - n) = 0 then (subList (n - 1 ) tl )
                        else subList (n - 1) (tl @ [hd])
        | [] -> [] ;;

我的编译器告诉我最后一行存在语法错误。 无论“ | []-> []”是最后一行还是上面的那一行,我都得到相同的结果。 当我取出嵌套的subList let时,语法错误不存在。 显然有一些关于嵌套让的内容,我只是不了解。

谢谢。

由于您只是从FP开始,因此建议您寻找最简单,最优雅的解决方案。 您正在寻找的是一种通过解决较小问题的解决方案来解决n问题的方法。

因此,关键问题是:如果已经具有可以产生列表的前(n-1)个元素的函数,那么如何产生列表的前n个元素?

然后,您需要解决“基本”案例,这些案例非常简单,答案显而易见。 对于这个问题,我想说两种基本情况:当n为0时,答案很明显;当n为0时,答案很明显。 当列表为空时,答案显而易见。

如果您通过这个工作,将会得到一个相当优雅的定义。

let rec firstk k xs = match xs with
| [] -> failwith "firstk"
| x::xs -> if k=1 then [x] else x::firstk (k-1) xs;;

您可能一直在寻找这个。

您要做的是迭代初始列表l ,然后在累加器中添加此列表的元素,直到n为0。

let take n l =
  let rec sub_list n accu l =
    match l with 
    | [] -> accu (* here the list is now empty, return the partial result *)
    | hd :: tl ->
      if n = 0 then accu (* if you reach your limit, return your result *)
      else (* make the call to the recursive sub_list function:
                 - decrement n, 
                 - add hd to the accumulator,
                 - call with the rest of the list (tl)*) 
  in
  sub_list n [] l

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM