@line =
------MMMMMMMMMMMMMMMMMMMMMMMMMM-M-MMMMMMMM
------SSSSSSSSSSSSSSSSSSSSSSSSSS-S-SSSSSDTA
------TIIIIIIIIIIIIITIIIVVIIIIII-I-IIIIITTT
我试图做的是一个散列,其中包含该行中每个单独元素的计数但由于某种原因它会不断地为我提供每个氨基酸的计数。我希望输出为:
M 35
S 32
I 28
答案 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