2016-02-16 3 views
1

У меня есть 2D-массивы (@AoA), которые содержат ссылки на другие массивы строк. Размер этого @AoA отличается каждый раз. Я хотел бы сравнить каждый из этих массивов строк друг с другом.
Для сравнения: первый массив строк друг с другом, я могу использовать что-то вроде этого:сравнить несколько массивов в perl

for (my $i=0; $i < $#AoA; $i++) { 
    my $lcm = List::Compare->new($aAoA[$i], $AoA[$i+1]); 
    my @intersection = $lcm->get_intersection; 
    if (@intersection) { 
     #some code here 
    } 

Но что лучший способ для сравнения каждого массива друг с другом? Я хотел бы результаты, как это:

 Arr1 Arr2  ….   ArrN 
Arr1 x  1 match 3 matches 0 matches 
Arr2   x  N matches 3 matches 
….       x  1 match 
ArrN         x 
+0

Если списки сортируются вы, вероятно, может сделать это гораздо более эффективно. Они? – neuhaus

+0

@ neuhasus Нет, они не отсортированы. Порядок элементов в каждом списке содержит определенную информацию. –

+0

Вы можете злоупотреблять Test :: Deep. – simbabque

ответ

0

Если вы чувствуете себя комфортно со списком :: Сравнение, то вы можете использовать его вместо моей функции intersect_count.

#!/usr/bin/perl 
use strict; 
use warnings; 
use List::MoreUtils 'uniq'; 
use List::Util 'any'; 

my @AoA = ([1,2,3,4,], [3,4,5,6], [4,7,8,9], [11,22,33]); 

my @hdrs = map "Array_$_", 1 .. @AoA; 
my $fmt = "%-10s" . "%-10s" x @hdrs . "\n"; 

printf $fmt, ' ', @hdrs; 

for (my $i=0; $i < $#AoA; $i++) { 
    my @matches; 
    for (my $j = $i+1; $j < @AoA; $j++) { 
     $matches[$j] = intersect_count($AoA[$i], $AoA[$j]); 
    } 
    printf $fmt, $hdrs[$i], map $_ // ' ', @matches; 
} 

sub intersect_count { 
    my ($a1, $a2) = @_; 
    my $cnt; 
    for my $item (uniq @$a1) { 
     $cnt += any {$item eq $_} uniq @$a2; 
    } 
    return $cnt; 
} 

Печатается

.   Array_1 Array_2 Array_3 Array_4 
Array_1    2   1   0 
Array_2      1   0 
Array_3         0 
+0

Спасибо большое! Помогает! –

Смежные вопросы