2

add / del / upd(= same)要素の数を比較して取得したい繰り返し値を持つ文字列の2つの配列があります。

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 に答える