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