我正在用 erlang 编写一个递归函数,给定一个元素 X 和一个列表,从列表中删除元素 X 并返回新列表。我相信我已经正确编写了它,但是,当我对其进行测试时,我陷入了无限循环..
delete(_,[]) -> [];
delete(X,[X|_]) -> [];
delete(X,[Y|YS]) ->
if X == Y -> YS;
true -> [Y] ++ delete(X,[YS]) % I believe the infinite loop is a result of this line..
end.
我对 erlang 非常陌生(这是我使用该语言的第二个项目),因此故障排除对我来说有点困难,但如果有人可以提供一些指导,我将不胜感激。预先感谢您!
最佳答案
delete(_,[]) -> []; %% ok removing anything from an empty list gives an empty list
delete(X,[X|_]) -> []; %% big mistake. If you find the element you want to remove on top
%% of the list, you must remove it and continue with the rest of the list
delete(X,[Y|YS]) ->
if X == Y -> YS; %% this will never occurs since you already test this case
%% in the previous clause. An the result should be delete(X,YS), not YS.
true -> [Y] ++ delete(X,[YS]) %% correct
end.
我不明白哪里有无限循环,但第二个子句会使递归调用过早停止。
所以你的代码应该是:
delete(_,[]) -> [];
delete(X,[X|Rest]) -> delete(X,Rest);
delete(X,[Y|YS]) -> [Y] ++ delete(X,[YS]).
但是我建议使用列表理解来实现非常短的代码和快速的执行(这是lists:filter/2中使用的代码):
delete(X,L) -> [Y || Y <- L, Y =/= X].
% ^ ^ ^
% | | |_ when Y different from X
% | |_________ with all the elements Y from L
% |__________________ make a list
在 shell 中定义函数,你会得到:
1> D = fun D(_,[]) -> [];
1> D(X,[X|R]) -> D(X,R);
1> D(X,[Y|R]) -> [Y] ++ D(X,R) end.
#Fun<erl_eval.36.90072148>
2> D(4,[1,2,3,4,5,6]).
[1,2,3,5,6]
3> D1 = fun(X,L) -> [Y || Y <- L, Y =/= X] end.
#Fun<erl_eval.12.90072148>
4> D1(4,[1,2,3,4,5,6]).
[1,2,3,5,6]
5>
关于recursion - Erlang-递归删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28726946/