在perl哈希中计数字母的问题

时间:2014-04-19 00:04:44

标签: perl hash count

小问题我有一些奇怪的原因。我正在尝试计算每个字符串中的字母数量并带回最高金额。以下是该文件的示例。

@line =

------MMMMMMMMMMMMMMMMMMMMMMMMMM-M-MMMMMMMM  
------SSSSSSSSSSSSSSSSSSSSSSSSSS-S-SSSSSDTA  
------TIIIIIIIIIIIIITIIIVVIIIIII-I-IIIIITTT  

我试图做的是一个散列,其中包含该行中每个单独元素的计数但由于某种原因它会不断地为我提供每个氨基酸的计数。我希望输出为:

M 35
S 32
I 28

2 个答案:

答案 0 :(得分:1)

在您的代码中:

foreach my $aa ($string) {
    $counter{$aa}++;
}   

($string)是一个由单个元素组成的列表,因此循环只运行一次,相当于$counter{ $string }++

您需要迭代字符串中的单个字符。您可以通过使用@Miller显示的空模式拆分字符串来实现。但是,如果您的字符串很大,那么您将创建许多可能对性能有害的大型列表。另一种方法是依次匹配每个字符(您需要决定是否要匹配换行符,空格等)。

#!/usr/bin/env perl

use strict;
use warnings;

my @lines = qw(
    ------MMMMMMMMMMMMMMMMMMMMMMMMMM-M-MMMMMMMM
    ------SSSSSSSSSSSSSSSSSSSSSSSSSS-S-SSSSSDTA
    ------TIIIIIIIIIIIIITIIIVVIIIIII-I-IIIIITTT
);

for my $line ( @lines ) {
    my $x = argmax( count_characters($line) );
    print "@$x\n";
}

sub count_characters {
    my $string = shift;
    my %freq;
    while ($string =~ /(.)/g) {
        $freq{ $1 } += 1;
    }
    return \%freq;
}

sub argmax {
    my $freq = shift;
    my ($argmax, $max) = each %$freq;
    while (my ($k, $v) = each %$freq) {
        ($v > $max) and ($argmax, $max) = ($k, $v);
    }
    return [$argmax, $max];
}

输出:

M 35
S 32
I 28

答案 1 :(得分:0)

您需要split该行来迭代字符:

use strict;
use warnings;

my %counter;

while (my $line = <DATA>) {
    chomp $line;

    for my $char (split '', $line) {
        $counter{$char}++;
    }
}

delete $counter{'-'};

while (my ($char, $count) = each %counter) {
    print "$char - $count\n";
}


__DATA__
------MMMMMMMMMMMMMMMMMMMMMMMMMM-M-MMMMMMMM
------SSSSSSSSSSSSSSSSSSSSSSSSSS-S-SSSSSDTA
------TIIIIIIIIIIIIITIIIVVIIIIII-I-IIIIITTT

输出:

A - 1
D - 1
M - 35
V - 2
I - 28
T - 6
S - 32