Я знаю, что вы уже получили ответ, но я прочитайте свой вопрос вчера, прежде чем отправиться на пляж, и я представлял себе это, пока я смотрел на «балет» кайт-серфинга, поэтому я его даю, он немного отличается от Стив, поэтому может быть интересно.
Списки: функция отображения не может использоваться в случае этого анализа, поскольку она применяет только данную функцию к каждому элементу списка для создания нового списка, который будет иметь одинаковую длину. Невозможно создать вложенный список. Как говорит @Steve, вам необходим аккумулятор для постепенного создания результатов.
Библиотека списков предлагает функцию для накопления терминов при переходе по списку: lists: foldl/3 (существует также foldr, mapfoldl и mapfoldr), проблема в этом случае заключается в определении аккумулятора, который поможет нам построить ожидаемый результат.
Самого простой список для анализа не имеет скобки, поэтому аккумулятор должен содержать список, в котором аккумулировать все элементы списка записей.
Но если мы столкнулись с "(", мы должны начать новый список, который будет содержать подсписку, которую мы должны вложить в результат. В этом случае нам нужен термин, содержащий список, мы могли бы поместить новый подсписок строить, и список, который был в процессе, когда мы сталкиваемся с «(»
простейшую структуру, которая может поместиться в 2 потребности в единой форме список списка:. [SublistInProgress|PreviousWork]
Теперь мы знаем форму нашего аккумулятора, мы можем определить функцию, которая должна ее построить, 3 случая:
- мы находим «(»: начать новый подсписок, а и «магазин» предыдущий аккумулятор
- мы находим «)»: добавить подсписок к предыдущему аккумуляторе
- любой другой случай добавить элемент в подсписке.
в оболочке:
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>
Примечание: Я аккумулировать элемент в списке, используя конструкцию [X|Hacc]
, а не HacC++ [X]
, это хорошая привычка, потому что он избегает, чтобы сделать совершенно новый список на каждом (и сделаю это, я избегу замечания от моего друга @ Хайнека-Пичи-Выходила: o). Поэтому я должен отменить список, когда захочу его сохранить.
Используя F в функции lists:foldl(F,[[]],L)
, мы получим список одного элемента, этот элемент будет обратным ожидаемому результату. Таким образом, мы должны внедрить этот вызов в библиотеку в определенной функции:
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