私はあなたが既に答えを得たけど、私ビーチに行く前にあなたの質問を読んでください。私はカイトサーフ "バレエ"を見ている間にこの1つを想像しました。私はそれを与えるので、それはスティーブワンとは少し違っています。
この分析の場合は、リストの各要素に所定の関数を適用して同じ長さの新しいリストを作成するため、map関数はこの分析の場合には使用できません。ネストされたリストを作成する方法はありません。 @Steveによれば、結果を徐々に構築するにはアキュムレータが必要です。
リストライブラリは、リストをたどる間に用語を累積する関数を提供します:リスト:foldl/3(foldr、mapfoldl、およびmapfoldrも存在します)。この場合の問題は、ビルドするのに役立つアキュムレータを定義することです期待される結果。
最も単純なリストには括弧がないため、アキュムレータにはエントリリストのすべての要素を累積するリストが含まれている必要があります。
しかし、「(」が出現した場合、結果にネストしなければならないサブリストを含む新しいリストを開始する必要があります。この場合、リストを含む用語が必要です。単一のフォームで2人のニーズに適合することができます構築するためのサブリスト、そして我々は「(」が発生した時に進行中であったリスト
最も簡単な構造は、リストのリストです:[SublistInProgress|PreviousWork]
今私たちはアキュムレータの形式を知っており、3つのケースを担当する関数を定義することができます:
- 我々は見つける「(」:我々はAを見つける
- 前のアキュムレータ新しいサブリストを起動し、そして「ストア」「)」:
- 前のアキュムレータにサブリストを追加し、他の場合には、追加要素を進行中のサブリストに追加します。シェルで
:
1> F = fun("(",Acc)-> [[],Acc];
1> (")",[SubList,[Hacc|Tacc]]) -> [[lists:reverse(SubList)|Hacc]|Tacc];
1> (X,[Hacc|Tacc]) -> [[X|Hacc]|Tacc] end.
#Fun<erl_eval.12.52032458>
注:私はむしろHacC++ [X]
よりも構造[X|Hacc]
を使用して、リスト内の要素を蓄積し、それはそれぞれで全く新しいリストを作るために回避するので、それは良い習慣ですステップ(これを行うと、私は友人@ Hynek-Pichi-Vychodilからの発言を避ける:o)。だから私はそれを保存したいときにリストを逆にしなければならない。
ファンクションlists:foldl(F,[[]],L)
でFを使用すると、1つの要素のリストが得られます。この要素は、期待される結果の逆です。
2> Transform = fun(L) -> [R] = lists:foldl(F,[[]],L),
2> lists:reverse(R) end.
#Fun<erl_eval.6.52032458>
、我々はそれをテストすることができます:だから我々は、特定の機能にライブラリにこの呼び出しを埋め込む必要があり、完璧な説明のための
3> L1 = ["0", "(", "1", "2", "3", ")"].
["0","(","1","2","3",")"]
4> L2 = ["0", "(", "11", "22", "(", "333", "444","(", "5555", ")", "666", ")", "77", "88", ")", "9"].
["0","(","11","22","(","333","444","(","5555",")","666",")",
"77","88",")","9"]
5> Transform(L1).
["0",["1","2","3"]]
6> Transform(L2).
["0",["11","22",["333","444",["5555"],"666"],"77","88"],"9"]
感謝を! – asyndrige