Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/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
Perl 如何计算可能包含重复元素的两个数组之间的交集?_Perl - Fatal编程技术网

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

Perl 如何计算可能包含重复元素的两个数组之间的交集?,perl,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,但我想得到2 3 4 另

如何计算两个数组的交集(公共元素)?我尝试使用以下代码:

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
,但我想得到
2 3 4

另一个例子:

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

这应该返回
56774
,而不是
5676774
。如何实现这一点?

在第一个示例中,您已经消除了所需输出中的重复元素。在你的第二个例子中,你还没有——我甚至不明白你想要的结果(因此,我将解决您所说的第一个示例输出所需的问题

更改:

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

@isect=grep{exists$original{$}和$original{$}++<2}@array2;
产生:

2 3 4第一个例子

第二个例子是5 6 7 4

测试代码:

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

print intersect( \@array1, \@array2);

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

print intersect( \@array1, \@array2);


sub intersect {
    my ($first, $second) = @_;
    my @array1 = @{ $first };
    my @array2 = @{ $second };
    my %original = ();
    my @isect = ();
    map { $original{$_} = 1 } @array1;
    @isect = grep { exists $original{$_} and   $original{$_}++ < 2 } @array2;
    return "@isect\n";
    }
my@array1=(1,2,3,3,3,4);
my@array2=(2,3,4,4,4);
打印相交(\@array1,\@array2);
@数组1=(5,6,7,7,1,4);
@数组2=(5,6,7,6,7,7,4,4,4);
打印相交(\@array1,\@array2);
子相交{
我的($first,$second)=@;
my@array1=@{$first};
my@array2=@{$second};
我的%original=();
我的@isect=();
map{$original{$}=1}@array1;
@isect=grep{exists$original{$}和$original{$}++<2}@array2;
返回“@isect\n”;
}

perldoc perlfaq4
有答案

这是它提供的多用途代码

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;
}

在第二个示例中,每个数组中有三个7,因此他们希望结果也包含三个7。您不应该不必要地复制这些数组,不应该将空列表分配给已经为空的变量,第一个
映射应该是
for
循环的
,以及输出格式(
“@isect\n”
)应该在sub之外完成。这将给出
my%original;$original{$}=1 for@$first;返回grep{exists$original{$}和$original{$}++<2}@$second;
,最好写为
my%original=map{$}$}@$first;返回grep{delete($original{$}})@$second;
。但是像这件衣服一样,我没有提到,这不是OP需要的。ikegami:我试着让我的日常工作看起来尽可能像最初的一样。但是因为我没有真正理解这个问题,我不应该麻烦。很抱歉浪费带宽。
map
是“映射”的意思你的语句
map{$original{$}=1}@array1
通过创建一个新的列表然后丢弃它来滥用它。正确的方法是
$original{$}=1 for@array1
my%original=map{$}@array1
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
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;
}