-2

如果我有一个多行数组,它包含例如以下整数,每行具有不同数量的整数:

1 1 1 2 1 1
2 1 4 1
2 1 1 3 1 6

如何将它转换为 perl 中的计数数组,对于没有计数的键为零?我可以使用 map 为单个数组案例做这件事,但我正在努力处理这个多行案例/数组案例的数组。

#For line 1, 1 => 5, 2 => 1
#For line 2, 1 => 2, 2 => 1, 4 => 1
#For line 3, 1 => 3, 2 => 1, 3 => 1, 6 => 1

所以结果看起来像这样:

5 1 0 0 0 0
2 1 0 1 0 0
3 1 1 0 0 1

谢谢!

4

4 回答 4

3

这似乎可以满足要求。它做了一个显而易见的事情,即构建一个计数哈希数组,然后在哈希的键中找到最大值以构建一个显示

use strict;
use warnings;

use feature 'say';

my @data;

while (<DATA>) {
  next unless /\S/;
  my %counts;
  $counts{$_}++ for split;
  push @data, \%counts;
}

my $max = 0;
for (map keys %$_, @data) {
  $max = $_ unless $max >= $_;
}

for my $row (@data) {
  say join ' ', map $row->{$_} // 0, 1 .. $max;
}

__DATA__

1 1 1 2 1 1
2 1 4 1
2 1 1 3 1 6

输出

5 1 0 0 0 0
2 1 0 1 0 0
3 1 1 0 0 1
于 2012-09-04T13:22:57.860 回答
1

ETA:修复了对负矩阵值的支持。假设不会出现浮点数,因为需要零值。

使用多维数组的技巧是记住数组只能包含标量值。在这种情况下,每个标量值都是对数组的引用。

如果您的矩阵可以包含正整数以外的其他值,则必须使用散列作为数据存储。

在下面的打印中,我使用定义或运算符来区分未初始化(零)计数。

use strict;
use warnings;
use Data::Dumper;
use List::Util qw(max min);

my @a = (
    [qw(1 1 1 2 1 1)],
    [qw(2 1 4 1)],
    [qw(2 1 1 3 1 6)],
);

my @res;
my ($max, $min);

for my $aref (@a) {      # each array element is an array ref
    my %count;
    for (@$aref) {       # the array elements of each ref
        $count{$_}++;    # count the numbers
    }
    $max = max(@$aref, $max // ());
    $min = min(@$aref, $min // ());
    push @res, \%count;
}
for my $href (@res) {
    print join " ", map $href->{$_} // 0, $min .. $max;
    print "\n";
}
print Dumper \@res;

输出:

5 1 0 0 0 0
2 1 0 1 0 0
3 1 1 0 0 1
$VAR1 = [
          {
            '1' => 5,
            '2' => 1
          },
          {
            '4' => 1,
            '1' => 2,
            '2' => 1
          },
          {
            '6' => 1,
            '1' => 3,
            '3' => 1,
            '2' => 1
          }
        ];

请注意缺少的零值。可以使用map类似于 print 语句中的语句添加这些语句。

于 2012-09-04T13:39:37.560 回答
0

怎么样:

use strict;
use warnings;
use Data::Dump qw(dump);

while (<DATA>) {
    chomp;
    my @count = (0) x 7;
    $count[$_]++ for split;
    shift @count;
    dump @count;
}
__DATA__
1 1 1 2 1 1
2 1 4 1
2 1 1 3 1 6

输出:

(5, 1, 0, 0, 0, 0)
(2, 1, 0, 1, 0, 0)
(3, 1, 1, 0, 0, 1)
于 2012-09-04T13:20:55.377 回答
-1
use warnings;
use strict;
use Data::Dumper;
my @a = ([1, 1, 1, 2, 1, 1], [2, 1, 4, 1], [2, 1, 1, 3, 1, 6]);
my @output = map { 
  my @in = (0, 0, 0, 0, 0, 0);
  $in[$_-1]++ for @$_;
  \@in;
} @a;
print Dumper(\@output), "\n";
于 2012-09-04T13:16:11.533 回答