如何计算可能包含重复元素的两个数组之间的交集?

时间:2017-03-12 00:19:30

标签: perl

如何计算两个数组的交集(常用元素)?我试过这段代码:

my @array1 = (1, 2, 3, 3, 3, 3, 4);
my @array2 = (2, 3, 4, 4, 4);
my %original = ();
my @isect = ();

map { $original{$_} = 1 } @array1;
@isect = grep { $original{$_} } @array2;

print "@isect\n";

结果为2 3 4 4 4,但我想获得2 3 4

另一个例子:

@array1 = (5, 6, 7, 7, 7, 1, 4);
@array2 = (5, 6, 7, 6, 7, 7, 4, 4, 4);

这应该返回5 6 7 7 7 4,而不是5 6 7 6 7 7 4 4 4。我怎么能这样做?

3 个答案:

答案 0 :(得分:5)

my @array1 = ( 5, 6, 7,    7, 7, 1, 4       );
my @array2 = ( 5, 6, 7, 6, 7, 7,    4, 4, 4 );

my %counts;
++$counts{$_} for @array1;
my @common = grep { --$counts{$_} >= 0 } @array2;

say "@common";  # 5 6 7 7 7 4

答案 1 :(得分:0)

perldoc perlfaq4有答案

How do I compute the difference of two arrays? How do I compute the intersection of two arrays?

这是它提供的多功能代码

my (@union, @intersection, @difference);

my %count = ();

foreach my $element (@array1, @array2) {
    $count{$element}++
}

foreach my $element (keys %count) {
    push @union, $element;
    push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
}

答案 2 :(得分:-2)

在您的第一个示例中,您已删除所需输出中的重复元素。在你的第二个,你没有 - 我甚至不理解所期望的结果。 :(因此,我会解决你所说的第一个示例输出所需的问题。

更改:

Option Explicit

Private Sub CommandButton1_Click()

    Dim opt As MSForms.OptionButton
    Dim i As Long

    For i = 1 To 6
        Set opt = UserForm1.Controls("p" & i & "OptionButton")
        If opt.Value = True Then
            MsgBox opt.Name & ":" & opt.Value
        End If
    Next i
End Sub

为:

@isect = grep { $original{$_} } @array2;

产生

第一个例子

2 3 4

5 6 7 4为第二个例子。

测试代码:

@isect = grep { exists $original{$_} and   $original{$_}++ < 2 } @array2;