如何在erlang中将字符串列表拆分为给定数量的列表

如何在erlang中将字符串列表拆分为给定数量的列表,erlang,Erlang,给定一个列表和一个整数,我想将该列表拆分为指定数量的列表(在列表中) 例如: 输入: [1,2,3,4,5,6,7,8,9], 3 输出: [[1,2,3],[4,5,6],[7,8,9]] 什么是一种干净高效的方法?您可以使用列表:split/2实现以下目的: divide(L, N) -> divide(L, N, []). divide([], _, Acc) -> lists:reverse(Acc); divide(L, N, Acc) when len

给定一个列表和一个整数,我想将该列表拆分为指定数量的列表(在列表中)

例如:

输入:

[1,2,3,4,5,6,7,8,9], 3
输出:

[[1,2,3],[4,5,6],[7,8,9]]

什么是一种干净高效的方法?

您可以使用
列表:split/2
实现以下目的:

divide(L, N) ->
    divide(L, N, []).
divide([], _, Acc) ->
    lists:reverse(Acc);
divide(L, N, Acc) when length(L) < N ->
    lists:reverse([L|Acc]);
divide(L, N, Acc) ->
    {H,T} = lists:split(N, L),
    divide(T, N, [H|Acc]).
divide(L,N)->
除以(L,N,[])。
除法([],u,Acc)->
清单:反向(Acc);
当长度(L)
列表:反向([L|Acc]);
除法(左、右、Acc)->
{H,T}=list:split(N,L),
除以(T,N,[H | Acc])。
第一个函数,
divide/2
,作为入口点。它只调用辅助函数
divide/3
,初始累加器值为空列表,然后
divide/3
完成所有工作。
divide/3
的第一个子句在列表完成处理后匹配,因此它只是反转累加器并返回该值。第二个子句处理
L
的长度小于请求的
N
值的情况;它通过将
Acc
L
预加,然后返回新累加器的相反方向,来创建一个新累加器。第三个子句首先调用
lists:split/2
,将传入列表拆分为
H
,它是
N
元素的列表,而
T
是列表的其余部分。然后它递归地调用自己,传递
T
作为新的列表值,传递原始的
N
值,以及一个新的累加器,该累加器由
H
作为第一个元素,原始累加器
Acc
作为尾部组成。

每个分区的writed by calls
length/1
保护(N^2)。这让我很烦恼,因为它可以在
O(N)
中完成,我是一个性能怪胎。它可以通过多种方式完成,例如有一种:

divide(L, N) when is_integer(N), N > 0 ->
    divide(N, 0, L, []).

divide(_, _, [], Acc) ->
    [lists:reverse(Acc)];
divide(N, N, L, Acc) ->
    [lists:reverse(Acc) | divide(N, 0, L, [])];
divide(N, X, [H|T], Acc) ->
    divide(N, X+1, T, [H|Acc]).
或者作为Steve解决方案的修改

divide(L, N) ->
    divide(L, N, []).

divide([], _, Acc) ->
    lists:reverse(Acc);
divide(L, N, Acc) ->
    try lists:split(N, L) of
        {H,T} -> divide(T, N, [H|Acc])
    catch
        error:badarg ->
            lists:reverse([L|Acc])
    end.
或者更简单:

divide([], _) -> [];
divide(L, N) ->
    try lists:split(N, L) of
        {H,T} -> [H|divide(T, N)]
    catch
        error:badarg -> [L]
    end.