Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang 删除列表元素只发生一次_Erlang - Fatal编程技术网

Erlang 删除列表元素只发生一次

Erlang 删除列表元素只发生一次,erlang,Erlang,我在erlang中有一个包含整数值的列表。 我想删除只出现一次的值(不是重复的) 我是二郎的新手。我尝试了一种方法,首先使用list:sort()对它们进行排序,然后如果旁边的成员相同,则删除该成员。 我在尝试迭代列表时遇到问题。如果你能告诉我怎么做,那将非常有帮助。迭代列表的一种方法(结果将返回一个新列表)是使用递归和模式匹配 在对列表排序之后,您希望迭代该列表,并检查它不仅与下一个元素不同,而且在它之前没有其他相等的元素。考虑列表 [3,3,3,5,5] < /代码>如果你只检查下一个元素,

我在erlang中有一个包含整数值的列表。 我想删除只出现一次的值(不是重复的)

我是二郎的新手。我尝试了一种方法,首先使用
list:sort()
对它们进行排序,然后如果旁边的成员相同,则删除该成员。
我在尝试迭代列表时遇到问题。如果你能告诉我怎么做,那将非常有帮助。

迭代列表的一种方法(结果将返回一个新列表)是使用递归和模式匹配

在对列表排序之后,您希望迭代该列表,并检查它不仅与下一个元素不同,而且在它之前没有其他相等的元素。考虑列表<代码> [3,3,3,5,5] < /代码>如果你只检查下一个元素,最后的<代码> 3 /代码>也将是唯一的,这是不正确的。< /P> 这是一个工作程序,我使用了一个计数器来处理上述情况。请参阅使用
[H|T]
对列表进行迭代的语法。您可能会看到更多的案例,并阅读更多有关它的信息

测试

7> test:remove_unique([1,2,3,3,3,5,5,6,7,7]).
[7,7,5,5,3,3,3]
8> test:remove_unique([1,2,3,3,3,5,5,6,7,8]).
[5,5,3,3,3]

使用map对值进行计数,然后过滤不存在的值

-module(test).
-export([remove_unique/1]).

remove_unique(L) ->
    Count = lists:foldl(fun count/2, #{}, L),
    lists:filter(fun(X) -> maps:get(X, Count) =/= 1 end, L).

count(X, M) ->
    maps:put(X, maps:get(X, M, 0) + 1, M).
和测试:

1> c(test).
{ok,test}
2> test:remove_unique([1,2,3,3,3,5,5,6,7,7]).
[3,3,3,5,5,7,7]
3> test:remove_unique([1,2,3,3,3,5,5,6,7,8]).
[3,3,3,5,5]
4> test:remove_unique([1,3,2,1,2,2]).        
[1,2,1,2,2]
multiple(L)->
M=L——列表:usort(L),

[X | | X这是我在发布问题时第一次看到这个问题时写的一个解决方案,它使用与@a.Sarid的递归/模式匹配答案相同的逻辑,只是我使用了“Last”参数而不是计数

-module(only_dupes).

-export([process/1]).

process([]) -> [];
process(L) when is_list(L) ->
  [H|T] = lists:sort(L),
  lists:sort(process(undefined, H, T, [])).

process(Last, Curr, [], Acc)
  when Curr =/= Last ->
  Acc;

process(_Last, Curr, [], Acc) ->
  [Curr | Acc];

process(Last, Curr, [Next | Rest], Acc) 
  when Curr =/= Last, Curr =/= Next ->
  process(Curr, Next, Rest, Acc);

process(_Last, Curr, [Next | Rest], Acc) ->
  process(Curr, Next, Rest, [Curr | Acc]).

谢谢你的帮助!有没有办法不中断列表的顺序而不使用排序?是的,只需以同样的方式迭代,每次检查元素是否再次出现在列表上。如果出现,请将其添加到输出列表中,否则,请不要添加。@Muhammadaad:查看我的简单解决方案。很好的解决方案,但有一个缺陷,O(n^2)复杂性。我知道,没有关于列表的典型长度的指示,这个解决方案在我的电脑上快了250个元素,使用map的过滤器变得越来越有效。实际上,你的解决方案非常聪明,它使用了尽可能多的BIF,这使得短列表的速度非常快。谢谢你的最佳解决方案@HynekVery很好的使用地图的简化解决方案。出于好奇,
maps:get
?@A.Sarid:O(1)的时间复杂度在理论上是多少,但在实践中是O(logN)。我没有听说或看到过会有O(1)的技术真正未绑定的K/V存储(包括内存中的线性寻址阵列或内存本身)的访问时间,但为什么会这样,这将是一个漫长的讨论。因此,如果考虑真正未绑定的解决方案,此解决方案是O(N*logN)。
1> c(test).
{ok,test}
2> test:remove_unique([1,2,3,3,3,5,5,6,7,7]).
[3,3,3,5,5,7,7]
3> test:remove_unique([1,2,3,3,3,5,5,6,7,8]).
[3,3,3,5,5]
4> test:remove_unique([1,3,2,1,2,2]).        
[1,2,1,2,2]
multiple(L) ->
    M = L -- lists:usort(L),
    [X || X <- L , lists:member(X,M)].
-module(only_dupes).

-export([process/1]).

process([]) -> [];
process(L) when is_list(L) ->
  [H|T] = lists:sort(L),
  lists:sort(process(undefined, H, T, [])).

process(Last, Curr, [], Acc)
  when Curr =/= Last ->
  Acc;

process(_Last, Curr, [], Acc) ->
  [Curr | Acc];

process(Last, Curr, [Next | Rest], Acc) 
  when Curr =/= Last, Curr =/= Next ->
  process(Curr, Next, Rest, Acc);

process(_Last, Curr, [Next | Rest], Acc) ->
  process(Curr, Next, Rest, [Curr | Acc]).