计算perl中每个行位置的每个字符的出现次数

时间:2015-12-07 17:47:56

标签: perl hashmap idiomatic

与问题类似 unix - count occurrences of character per line/field  但是对于线上每个位置的每个角色。

给出每1e7行约500个字符的文件, 我想要一个二维的汇总结构 $摘要{' A'' B'' C'' 0'' 1'&# 39; 2'} [pos 0..499] = count_integer 它显示了每个字符在该行的每个位置使用的次数。尺寸顺序都可以。

我的第一个方法在阅读时做了++ summary {char} [pos], 但由于很多线都是一样的, 首先计算相同的线条要快得多 然后一次总结摘要{char} [pos] + = n

是否有比以下类似C的2d循环更惯用或更快的方式?

#!perl 
my ( %summary, %counthash ); # perl 5.8.9

sub method1 {
    print "method1\n";
    while (<DATA>) {
        my @c = split( // , $_ );
        ++$summary{ $c[$_] }[$_] foreach ( 0 .. $#c );
    }    # wend
} ## end sub method1

sub method2 {
    print "method2\n";
    ++$counthash{$_} while (<DATA>);    # slurpsum the whole file

    foreach my $str ( keys %counthash ) {  
        my $n = $counthash{$str};
        my @c = split(//, $str);
        $summary{ $c[$_] }[$_] += $n foreach ( 0 .. $#c );
    }    #rof  my $str
} ## end sub method2

# MAINLINE
if (rand() > 0.5) { &method1 } else { &method2 }
print "char $_ : @{$summary{$_}} \n" foreach ( 'a', 'b' );
# both methods have this output summary
# char a : 3 3 2 2 3 
# char b : 2 2 3 3 2 
__DATA__
aaaaa
bbbbb
aabba
bbbbb
aaaaa

1 个答案:

答案 0 :(得分:1)

根据数据的形成方式,method2可能比方法1更快或更慢。

但是一个很大的区别就是使用unpack而不是split。

use strict;
use warnings;
my ( %summary, %counthash ); # perl 5.8.9

sub method1 {
    print "method1\n";
    my @l= <DATA>;
    for  my $t(1..1000000) {
        foreach (@l) {
            my @c = split( // , $_ );
            ++$summary{ $c[$_] }[$_] foreach ( 0 .. $#c );
        }    
    }    # wend
} ## end sub method1

sub method2 {
    print "method2\n";
    ++$counthash{$_} while (<DATA>);    # slurpsum the whole file
    for  my $t(1..1000000) {
        foreach my $str ( keys %counthash ) {  
            my $n = $counthash{$str};
            my $i = 0;
            $summary{ $_ }[$i++] += $n foreach ( unpack("c*",$str) );
        }    
    }
} ## end sub method2

# MAINLINE
#method1();
method2();
print "char $_ : ". join (" ", @{$summary{ord($_)}}). " \n"
    foreach ( 'a', 'b' );
# both methods have this output summary
# char a : 3 3 2 2 3 
# char b : 2 2 3 3 2 
__DATA__
aaaaa
bbbbb
aabba
bbbbb
aaaaa

跑得快得多。 (6而不是我电脑上的7.x秒)