我的目标是有一个split n l
函数,它以一个N
和一个列表作为参数,并尝试将该列表分成N
个大小相等的列表。
函数的签名是:val split : int -> 'a list -> 'a list list = <fun>
list:[0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20]
的执行将给出,例如:
[[0; 1; 2; 3; 4; 5; 6]; [7; 8; 9; 10; 11; 12; 13]; [14; 15; 16; 17; 18; 19; 20]];
我试图用一本我正在使用的OCaml书和我发现的函数来激励自己,比如
let take l n =
if n < 0 then
raise (Invalid_argument "take")
else
let rec take_inner r l n =
if n = 0 then
List.rev r
else
match l with
| [] -> raise (Invalid_argument "take")
| h :: t -> take_inner (h :: r) t (n - 1) in
take_inner [] l n
let drop l n =
let rec drop_inner n l =
match l with
| [] -> raise (Invalid_argument "drop")
| _ :: t ->
if n = 1 then
t
else
drop_inner (n - 1) t in
if n < 0 then
raise (Invalid_argument "drop")
else if n = 0 then
l
else
drop_inner n l
let rec split n l =
try take l n :: split n (drop l n)
with _ -> (
match l with
| [] -> []
| _ -> [l])
我觉得我已经接近我想要实现的目标了,尽管这个版本给出了一个N个大小的子列表,而不是N个子列表。
我只是不知道如何把所有的东西都调整到一起来达到我想要的效果。
有什么建议吗?谢谢。
如果要将初始列表拆分为n
个大小相等的列表,那么首先需要确定每个列表的大小。为此,您需要计算原始列表的大小并将其除以n
。如果它被平均分割,那么这就是每个列表的长度,并且您已经知道如何生成给定长度的列表。如果不能平均分配,则可以生成错误或缩短最后一个列表,这取决于您想从函数中得到什么。