簡體   English   中英

如何在erlang中將字符串列表拆分為給定數量的列表

[英]How to split a list of strings into given number of lists in erlang

給定一個列表和一個整數,我想將該列表拆分為指定數量的列表(在列表內部)。

例如:

輸入:

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

輸出:

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

什么是清潔有效的方法?

您可以為此使用lists: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/2用作入口點。 它僅使用空列表的初始累加器值調用輔助函數divide/3 ,然后divide/3完成所有工作。 當列表已被完全處理時, divide/3的第一個子句匹配,因此它只是反轉累加器並返回該值。 第二個子句處理L的長度小於請求的N值的情況; 它通過在Acc前面加上L ,然后返回該新累加器的相反值來創建一個新累加器。 第三個子句首先調用lists:split/2 ,將傳入的列表拆分為H (它是N元素的列表),以及T (列表的其余部分)。 然后,它遞歸調用自身,將T作為新的列表值,原始N值以及一個新的累加器,該累加器由H作為第一個元素,而原始累加器Acc作為尾部。

史蒂夫·維諾斯基Steve Vinoski)編寫的解決方案為每個分區調用了length/1作為保護,使其變為 O(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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM