使用整数列表,例如:
[1;2;3;4;5;6;7;8;9]
如何从上面创建一个整数列表列表,所有新列表都具有相同的指定长度?
例如,我需要从:
[1;2;3;4;5;6;7;8;9] to [[1;2;3];[4;5;6];[7;8;9]]
要拆分的数字是 3?
谢谢你的时间。
使用整数列表,例如:
[1;2;3;4;5;6;7;8;9]
如何从上面创建一个整数列表列表,所有新列表都具有相同的指定长度?
例如,我需要从:
[1;2;3;4;5;6;7;8;9] to [[1;2;3];[4;5;6];[7;8;9]]
要拆分的数字是 3?
谢谢你的时间。
所以你真正想要的是一个类型的函数
val split : int list -> int -> int list list
它需要一个整数列表和一个子列表大小。一个更通用的呢?
val split : 'a list -> int -> 'a list list
下面是实现:
let split xs size =
let (_, r, rs) =
(* fold over the list, keeping track of how many elements are still
missing in the current list (csize), the current list (ys) and
the result list (zss) *)
List.fold_left (fun (csize, ys, zss) elt ->
(* if target size is 0, add the current list to the target list and
start a new empty current list of target-size size *)
if csize = 0 then (size - 1, [elt], zss @ [ys])
(* otherwise decrement the target size and append the current element
elt to the current list ys *)
else (csize - 1, ys @ [elt], zss))
(* start the accumulator with target-size=size, an empty current list and
an empty target-list *)
(size, [], []) xs
in
(* add the "left-overs" to the back of the target-list *)
rs @ [r]
如果您为此获得额外积分,请告诉我!;)
您提供的代码是一种从列表前面删除给定数量元素的方法。继续的一种方法可能是保留此函数(可能稍微清理一下)并使用外部函数来处理整个列表。为了让这个工作更容易,你的函数可能还想返回列表的其余部分(这样外部函数可以很容易地判断出仍然需要分段的内容)。
不过,您似乎想用一个函数来解决问题。如果是这样,我看到的主要缺失是您已经剪掉的碎片的累加器。而且你也不能在达到计数时退出,你必须记住你刚刚剪下的部分,然后以同样的方式处理列表的其余部分。
如果我自己解决这个问题,我会尝试概括问题,以便递归调用在所有情况下都可以提供帮助。可能有效的方法是让第一部分比其他部分短。这样你就可以把它写成一个函数,没有累加器(只是递归调用)。
我可能会这样做:
let split lst n =
let rec parti n acc xs =
match xs with
| [] -> (List.rev acc, [])
| _::_ when n = 0 -> (List.rev acc, xs)
| x::xs -> parti (pred n) (x::acc) xs
in let rec concat acc = function
| [] -> List.rev acc
| xs -> let (part, rest) = parti n [] xs in concat (part::acc) rest
in concat [] lst
请注意,如果n
不均分,我们将宽容List.length lst
。示例:
split [1;2;3;4;5] 2
给出[[1;2];[3;4];[5]]
最后说明:代码非常冗长,因为 OCaml 标准库非常简单:/ 使用不同的库,我相信这可以更简洁。
let rec split n xs =
let rec take k xs ys = match k, xs with
| 0, _ -> List.rev ys :: split n xs
| _, [] -> if ys = [] then [] else [ys]
| _, x::xs' -> take (k - 1) xs' (x::ys)
in take n xs []