2

我有两个具有重复值的字符串数组,我想比较它们并获取 add/del/upd(=same) 元素的数量:

my @array1 = ("aaa", "bbb", "ccc", "eee", "eee");
my @array2 = ("aaa", "aaa", "bbb", "ccc", "ccc", "ddd", "fff");

我需要类似的东西:

add: 4
del: 2
upd: 3

我试过List::Compare

my @array1 = ("aaa", "bbb", "ccc", "eee", "eee");
my @array2 = ("aaa", "aaa", "bbb", "ccc", "ccc", "ddd", "fff");

my $lc = List::Compare->new(\@array1, \@array2);        
print Dumper "intersection (upd): ".scalar($lc->get_intersection);
print Dumper "only first   (del): ".scalar($lc->get_unique);
print Dumper "only second  (add): ".scalar($lc->get_complement);

但它不适用于重复值:

$VAR1 = 'intersection (upd): 3';
$VAR1 = 'only first   (del): 1';
$VAR1 = 'only second  (add): 2';

我怎么解决这个问题?

4

2 回答 2

3

这将满足您的需求。

我相信机制是明确的。如果您需要进一步的解释,请再次询问。

use strict;
use warnings;

my @array1 = qw( aaa bbb ccc eee eee );
my @array2 = qw( aaa aaa bbb ccc ccc ddd fff );

my %data;

$data{$_}[0]++ for @array1;
$data{$_}[1]++ for @array2;

my ($add, $del, $upd) = (0, 0, 0);

for (values %data) {
  my ($a1, $a2) = map $_ // 0, @$_[0,1];
  if ($a1 < $a2) {
    $upd += $a1;
    $add += $a2 - $a1;
  }
  else {
    $upd += $a2;
    $del += $a1 - $a2;
  }
}

printf "add/del/upd = %d/%d/%d\n", $add, $del, $upd;

输出

add/del/upd = 4/2/3
于 2012-07-02T10:23:52.643 回答
2

您正在使用多重集(又名包)(元素可以多次出现),而不是集(元素是唯一的)。使用Set::Bag

于 2012-07-02T09:50:57.707 回答