我有一个清单,我想要“解压缩-扁平化”。基本上,这意味着如果我有一个项目列表:
[a, b, c, d, e, f, g]我想把它变成一个列表,如下所示:
[[a, d, g], [b, e], [c, f]]到目前为止,我的解决方案如下所示:
unzipflatten(NumberOfLists, List) ->
lists:map(fun(Start) ->
lists:map(fun(N) ->
lists:nth(N, List)
end,
lists:seq(Start, length(List), NumberOfLists))
end,
lists:seq(1, NumberOfLists)).我对Erlang非常陌生,所以我想知道我是不是错过了一些可以做我想做的事情的标准库函数,或者有没有更"Erlangish“的方法来做到这一点,或者我上面的解决方案的性能是否会很糟糕。
发布于 2010-11-23 12:09:44
我认为这是一种更"Erlangish“的方法来做这件事。基本上,您将创建将作为结果的列表列表,并使用两个列表来像队列一样管理这些列表。"Heads“列表包含您将添加到下一页的列表,而"Tails”列表是最近添加到的列表。当Heads为空时,您只需反转Tails并将其用作新的Heads。在返回结果之前,您需要反转Tails和Heads中的所有列表,然后将Heads按原样附加到反转的Tails中。请原谅令人困惑的变量名称,我认为在Erlang程序中想出几个好的名称来分解列表是最困难的部分;)
unzipflatten(NumberOfLists, List) when NumberOfLists > 0 ->
unzipflatten(List, lists:duplicate(NumberOfLists, []), []).
unzipflatten([], Heads, Tails) ->
[lists:reverse(L) || L <- lists:reverse(Tails, Heads)];
unzipflatten(L, [], Tails) ->
unzipflatten(L, lists:reverse(Tails), []);
unzipflatten([Elem | Rest], [Head | Tail], Tails) ->
unzipflatten(Rest, Tail, [[Elem | Head] | Tails]).也可以以非尾递归方式进行“解压缩”阶段,以避免列表:反向步骤,但这是一个更复杂的解决方案。如下所示:
unzipflatten(NumberOfLists, List) when NumberOfLists > 0 ->
unzipflatten({List, lists:duplicate(NumberOfLists, [])}).
unzipflatten({[], Heads}) ->
[lists:reverse(L) || L <- Heads];
unzipflatten({L, Heads}) ->
unzipflatten(unzipper({L, Heads})).
unzipper({[], Heads}) ->
{[], Heads};
unzipper({L, []}) ->
{L, []};
unzipper({[H | T], [Head | Tail]}) ->
{T1, Tail1} = unzipper({T, Tail}),
{T1, [[H | Head] | Tail1]}.发布于 2010-11-23 06:20:59
是的,性能会很糟糕(使用lists:nth的基本建议是:不要在不断增长的N中多次调用它!)。这样的东西应该更好(未经过测试):
unzipflatten(NumberOfLists, List) ->
unzipflatten(NumberOfLists, List, array:new(NumberOfLists, {default, []}), 0).
unzipflatten(_, [], Lists, _) ->
lists:map(fun lists:reverse/1, array:to_list(Lists));
unzipflatten(NumberOfLists, [H | T], Lists, CurrentIndex) ->
NewLists = array:set(CurrentIndex, [H | array:get(CurrentIndex, Lists)], Lists),
unzipflatten(NumberOfLists, T, NewLists, (CurrentIndex + 1) rem NumberOfLists).https://stackoverflow.com/questions/4249324
复制相似问题