二郎神:从列表中选择唯一的项目,使用递归(Erlang: choosing unique items

2019-07-21 13:07发布

鉴于二郎山,如任何列表:

L = [foo, bar, foo, buzz, foo].

我怎么能只显示该列表的唯一项目,使用递归函数? 我不希望使用内置的功能,如名单功能之一(如果存在的话)。

在我的例子,我想要去将是一个新的列表,如

SL = [bar, buzz].

我的猜测是,我会用快速排序功能,应用过滤器之前,首先对列表进行排序,?

任何的意见都将会有帮助。 这个例子是在利尼的&Thompson的优秀“Erlang编程”一书的第3章练习的变化。

Answer 1:

我提出这一个:

unique(L) ->
    unique([],L).
unique(R,[]) -> R; 
unique(R,[H|T]) ->
    case member_remove(H,T,[],true) of
        {false,Nt} -> unique(R,Nt);
        {true,Nt} -> unique([H|R],Nt)
    end.

member_remove(_,[],Res,Bool) -> {Bool,Res};
member_remove(H,[H|T],Res,_) -> member_remove(H,T,Res,false);
member_remove(H,[V|T],Res,Bool) -> member_remove(H,T,[V|Res],Bool).

没有被检查的元件的所有出现重复和试验结果在一项所述的member_remove函数返回并将余下的尾巴。



Answer 2:

我可以做这种方式:)

get_unique(L) ->
    SortedL = lists:sort(L),
    get_unique(SortedL, []).

get_unique([H | T], [H | Acc]) ->
    get_unique(T, [{dup, H} | Acc]);
get_unique([H | T], [{dup, H} | Acc]) ->
    get_unique(T, [{dup, H} | Acc]);
get_unique([H | T], [{dup, _} | Acc]) ->
    get_unique(T, [H | Acc]);
get_unique([H | T], Acc) ->
    get_unique(T, [H | Acc]);
get_unique([], [{dup, _} | Acc]) ->
    Acc;
get_unique([], Acc) ->
    Acc.


Answer 3:

使用两个累加器。 一个让你看到,到目前为止,一个持有实际结果的要素。 如果您看到该项目的第一次(而不是在看表)预先准备的项目这两个列表和递归。 如果你以前见过的项目,递归之前,从你的结果(ACC)将其删除。

-module(test).

-export([uniques/1]).

uniques(L) ->
    uniques(L, [], []).

uniques([], _, Acc) ->
    lists:reverse(Acc);
uniques([X | Rest], Seen, Acc) ->
    case lists:member(X, Seen) of
        true -> uniques(Rest, Seen, lists:delete(X, Acc));
        false -> uniques(Rest, [X | Seen], [X | Acc])
    end.


Answer 4:

我觉得想法可能是:请检查您是否已经看到列表的头部。 如果是这样,跳过它,递归检查尾部。 如果没有 - 现任添加到结果,以“看到”并递归检查尾部。 检查如果你已经看到该项目最合适的结构设置。

所以,我提出以下几点:

 remove_duplicates(L) -> remove_duplicates(L,[], sets:new()). 

  remove_duplicates([],Result,_) -> Result;
  remove_duplicates([Head|Tail],Result, Seen) ->
    case sets:is_element(Head,Seen) of
      true -> remove_duplicates(Tail,Result,Seen);
      false -> remove_duplicates(Tail,[Head|Result], sets:add_element(Head,Seen))
    end.


Answer 5:

该解决方案只从列表中过滤掉重复。 可能需要在让它做你想做的建设。

remove_duplicates(List)->
    lists:reverse(removing(List,[])).

removing([],This) -> This;
removing([A|Tail],Acc) -> 
    removing(delete_all(A,Tail),[A|Acc]).

delete_all(Item, [Item | Rest_of_list]) ->
    delete_all(Item, Rest_of_list);
delete_all(Item, [Another_item| Rest_of_list]) ->
    [Another_item | delete_all(Item, Rest_of_list)];
delete_all(_, []) -> [].

编辑


Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\System32>erl
Eshell V5.9  (abort with ^G)
1> List = [1,2,3,4,a,b,e,r,a,b,v,3,2,1,g,{red,green},d,2,5,6,1,4,6,5,{red,green}].
[1,2,3,4,a,b,e,r,a,b,v,3,2,1,g,
 {red,green},
 d,2,5,6,1,4,6,5,
 {red,green}]
2> remove_duplicates(List).
[1,2,3,4,a,b,e,r,v,g,{red,green},d,5,6]
3>



Answer 6:

试试下面的代码

-module(util).

-export([unique_list/1]).

unique_list([]) -> [];
unique_list(L)  -> unique_list(L, []).

% Base Case
unique_list([], Acc) -> 
    lists:reverse(Acc);

% Recursive Part 
unique_list([H|T], Acc) ->
    case lists:any(fun(X) -> X == H end, T) of
        true  -> 
            unique_list(lists:delete(H,T), Acc);
        false -> 
            unique_list(T, [H|Acc])
end.


Answer 7:

唯一的(L) - >集:to_list(套:from_list(L))。



Answer 8:

unique(List) ->
    Set = sets:from_list(List),
    sets:to_list(Set).


Answer 9:

最简单的方法是使用功能与跟踪你已经拥有的元素的“蓄电池”。 所以,你会写这样一个函数

%unique_acc(累加器,List_to_take_from)。

你仍然可以有一个干净的功能,通过不出口蓄能器版本,而是出口它的调用者:

-module(uniqueness).
-export([unique/1]).

unique(List) ->
    unique_acc([], List).

如果从采取列表是空的,你就大功告成了:

unique_acc(Accumulator, []) ->
    Accumulator;

如果它不是:

unique_acc(Accumulator, [X|Xs]) ->
   case lists:member(X, Accumulator) of
       true  -> unique_acc(Accumulator, Xs);
       false -> unique_acc([X|Accumulator], Xs)
   end.

2个注意事项:
-这确实使用列表BIF - lists:member/2 。 您可以轻松地写出这样自己,虽然。
- 元素的顺序颠倒过来,从最初的名单所致。 如果你不喜欢这个,你可以定义unique/1lists:reverse(unique_acc([], List)) 甚至更好,自己写一个反向的功能! (这很简单)。



文章来源: Erlang: choosing unique items from a list, using recursion