我正在做 *Erlang编程 * 中的练习。
问题是
编写一个函数,给定一个嵌套列表的列表,该函数将返回一个平面列表。
示例:flatten([[1,[2,[3],[]]], [[[4]]], [5,6]]) ⇒ [1,2,3,4,5,6].
提示:使用concatenate
求解flatten
。
这是我的concatenate
函数
%% concatenate([[1,2,3], [], [4, five]]) ⇒ [1,2,3,4,five].
concatenate([X|Xs]) -> concat(X, Xs, []).
concat([X|Xs], T, L) -> concat(Xs, T, [X|L]);
concat([], [X|Xs], L) -> concat(X, Xs, L);
concat([], [], L) -> reverse(L).
我真的很想知道一种优雅的方法来实现flatten
。
UPDATE:我忘记了最重要的先决条件。是否可以只使用 * 递归 * 和 * 模式匹配 * 来解决这个问题?
6条答案
按热度按时间h5qlskok1#
我会尝试这种方式
测试
**UPD:**或者这种方式,没有保护和反向,只有递归调用和模式匹配。
z4bn682m2#
一些不同的解决方案,变得越来越聪明:
或
或
这些都是只有模式匹配和递归,但他们可以通过一些保护类型测试来改进。使用
++
是低效的,因为它每次都复制列表。lists
模块使用了带有保护类型测试的最后一个版本,而不是最后一个子句。ddrv8njm3#
漂亮简洁直白的版本:
rekjcdws4#
书中定义的concatenate/1作为一个扁平化函数工作,它只扁平化一层。(
[[1],[2]]
变成[1,2]
,[[[1]],[[2]]]
变成[[1],[2]]
,等等。)提示中建议的策略是完全扁平化,不是通过在flat/1中定义新逻辑,而是通过在flat/1的递归调用中使用concatenate/1。zhte4eai5#
问题的关键是“分而治之”。
另一个额外的功能“列表:反向”和一个运算符“++”用于节省编程时间。
对于您的测试:测试:my_flat([[1,[2,[3],[]]],[4],[5,6]],[]).
jvlzgdj96#
这里还有另一种选择,不使用累加器而用Erlang列表进行append操作(++):