从阵列中删除偶数量的重复项

gen*_*si5 0 arrays perl duplicates

我有一个阵列

[ 1, 0, 0, 0, 5, 2, 4, 5, 2, 2 ]
Run Code Online (Sandbox Code Playgroud)

我需要删除大量的重复项.

这意味着,如果一个值在数组中出现偶数次,则将它们全部删除,但如果它出现奇数次,则只保留一个.

上面数组的结果应该是

[ 1, 0, 2, 4 ]
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

ike*_*ami 5

删除重复项通常如下所示:

use List::Util 1.44 qw( uniqnum );

@a = uniqnum @a;
Run Code Online (Sandbox Code Playgroud)

要么

my %seen;
@a = grep { !$seen{$_}++ } @a;
Run Code Online (Sandbox Code Playgroud)

为了达到你想要的效果,我们只需要链条grep去除其他不需要的元素.

use List::Util 1.44 qw( uniqnum );

@a = uniqnum grep { $counts{$_} % 2 } @a;
Run Code Online (Sandbox Code Playgroud)

要么

my %seen;
@a = grep { !$seen{$_}++ } grep { $counts{$_} % 2 } @a;
Run Code Online (Sandbox Code Playgroud)

要么

my %seen;
@a = grep { ( $counts{$_} % 2 ) && !$seen{$_}++ } @a;
Run Code Online (Sandbox Code Playgroud)

上述解决方案依赖于每个值的计数.为此,我们可以使用以下内容:

my %counts;
++$counts{$_} for @a;
Run Code Online (Sandbox Code Playgroud)

全部一起:

my ( %counts, %seen );
++$counts{$_} for @a;
@a = grep { ( $counts{$_} % 2 ) && !$seen{$_}++ } @a;
Run Code Online (Sandbox Code Playgroud)

请注意,这些删除重复项的方法保留了元素的顺序(保留第一个副本).这更有效(O(N))然后涉及sort(O(N log N))以避免产生非确定性的东西.