1

「解凍-フラット化」したいアイテムのリストがあります。基本的にそれが意味するのは、私がアイテムのリストを持っている場合:

[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」な方法があるのか​​、または上記のソリューションのパフォーマンスが悪臭。

4

2 に答える 2

2

これは、これを行うためのより「Erlangish」な方法になると思います。基本的に、結果となるリストのリストを作成し、2つのリストを使用してそれらのリストをキューのように管理します。「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]).

また、lists:reverseステップを回避するために、末尾再帰ではない方法で「解凍」フェーズを実行することもできますが、それはより複雑な解決策です。このようなもの:

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-23T04:09:43.780 に答える
0

はい、パフォーマンスは悪臭を放ちます(使用するための基本的なアドバイス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).
于 2010-11-22T22:20:58.983 に答える