我正在努力学习Erlang中的递归,我正在读一本书.但是当遇到列表并仅返回重复元素的问题时,我正在撞墙.我尝试编写一个函数,它只返回唯一元素,然后从原始列表中删除它们.
adjacent_dups(L) -> L -- uniques(L).
uniques([]) -> [];
uniques([H|T]) -> [H | [X || X <- uniques(T), X /= H]].
Run Code Online (Sandbox Code Playgroud)
但是,当列表结构不合理时,这将不会给出正确的结果.
L = [7,3,4,3]
Run Code Online (Sandbox Code Playgroud)
我的代码将返回
adjacent_dups([7,3,4,3]) -> 3
Run Code Online (Sandbox Code Playgroud)
我怎样才能得到
adjacent_dups([7,3,4,3]) -> []
Run Code Online (Sandbox Code Playgroud)
在函数头中使用模式匹配来查找相邻的相同值:
adjacent_dups(L) ->
adjacent_dups(L, #{}).
adjacent_dups([], Acc) ->
maps:keys(Acc);
adjacent_dups([H,H|T], Acc) ->
adjacent_dups(T,maps:put(H,H,Acc));
adjacent_dups([_|T], Acc) ->
adjacent_dups(T, Acc).
Run Code Online (Sandbox Code Playgroud)
第一个函数adjacent_dups/1是要导出的.其余的,adjacent_dups/2是辅助功能.
该adjacent_dups/1函数创建一个空映射以adjacent_dups/2作为累加器的初始值传递给该映射.递归函数通常使用累加器.
第一个句子adjacent_dups/2处理传入列表已用尽或开始时为空的情况.在这种情况下,我们检索累加器映射的键; 这些是我们相邻的价值观.
第二个子句adjacent_dups/2使用模式匹配处理相邻值的大小写.在这种情况下,我们将值作为键和值添加到累加器映射,并使用列表的尾部递归调用自己.使用地图可以消除最终结果中的重复项.
最后一个句子adjacent_dups/2处理一个值没有相邻值的情况; 它只是使用列表的尾部和未修改的累加器进行递归调用.