我最初尝试编写这个而不是尾递归,正如http://www.erlang.org/doc/efficiency_guide/myths.html根据BEAM自己做的那样。它的工作原理,我只是想知道我的代码是否过于丑陋/低效。识字程序http://en.literateprograms.org/Selection_sort_%28Erlang%29中的那个似乎比我的版本简洁一点,但我觉得我有太多的参数很容易被理解。如果我对递归更有经验,我不确定我是否会有这种感觉。
-module(selection).
-export([selection/1]).
selection([H|T]) -> lists:reverse(selection(T,H,[],[])).
selection([],Min,[H|T],Acc) -> selection(T,H,[],[Min|Acc]);
selection([],Min,[],Acc) -> [Min|Acc];
selection([H|T],Min,Rest,Acc) when H < Min -> selection(T,H,[Min|Rest],Acc);
selection([H|T],Min,Rest,Acc) -> selection(T,Min,[H|Rest],Acc).
答案 0 :(得分:1)
这是一个版本:
-module(selection).
-export([selection/1]).
selection([]) -> [];
selection([H|T]) ->
{Min, Rest} = remove_min(H, T, []),
[Min | selection(Rest)].
remove_min(Min, [], Rest) -> {Min, Rest};
remove_min(SoFar, [H|T], Acc) when H < SoFar ->
remove_min(H, T, [SoFar|Acc]);
remove_min(Min, [H|T], Acc) -> remove_min(Min, T, [H|Acc]).
或者使用累加器指出YOUR ARGUMENT IS VALID但是没有反转的最大值:
selection([H|T]) -> selection(T,H,[],[]).
selection([],Max,[H|T],Acc) -> selection(T,H,[],[Max|Acc]);
selection([],Max,[],Acc) -> [Max|Acc];
selection([H|T],Max,Rest,Acc) when H > Max -> selection(T,H,[Max|Rest],Acc);
selection([H|T],Max,Rest,Acc) -> selection(T,Max,[H|Rest],Acc).
似乎两者的表现几乎相同。