返回列表的前 k 个元素。我的代码 returns 最后 k 个元素

Returning first k elements of a list. My code returns last k elements

我正在尝试 return 列表的前 k 个元素 xs。例如 take 2 [1; 2; 3] 应该输出 [1; 2]

我写了一个函数,但不是 return 第一个 k 个元素,而是 return 最后一个 k 个元素,如果 k 等于列表的长度,而不是 return 整个列表,它会失败。

这是我的代码

let rec take k = function
|[] -> failwith "take"
|x :: xs -> if k = List.length xs  then xs else take (List.length xs - k) xs

我该如何解决这个问题?

你需要回答递归编写的两个基本问题:

  1. 哪些案例是如此微不足道以至于答案显而易见?
  2. 如果给定一个非平凡的案例,我如何制作它的一个较小的实例,这样我就可以得到那个较小实例的答案只需使用我正在编写的相同函数1,然后通过一些简单步骤从那个较小的答案中找到我的完整答案?

对于这个问题,微不足道的情况(我会说)是当 k0 时,当给定的列表是空列表。

对于非平凡的情况,洞察力似乎是我可以获得列表的前 k 个元素(对于 k > 0) 通过获取列表 tail 的前 (k - 1) 个元素,然后添加 head 的原始列表到那个 2.

这不是您的代码所做的,所以这基本上就是它不起作用的原因:-)

作为旁注,我不认为要求任何列表(包括空列表)的前 0 个元素是错误的。


1 递归方法的本质是假设你已经掌握了它。

2这是因为身份length (x :: xs) = 1 + length xs.

只是换一种方式:

let take k l =
  let v =Array.of_list l in
  let v'=Array.make k 0 in
  Array.blit v 0 v' 0 k;
  Array.to_list v';;

测试:

# take 2 [1;2;3];;
- : int list = [1; 2]
# take 0 [1;2;3];;
- : int list = []
# take 4 [1;2;3];;
Exception: Invalid_argument "Array.blit".