【问题标题】:Problems counting letters in perl hash在 perl 哈希中计算字母的问题
【发布时间】:2014-04-19 13:46:22
【问题描述】:

由于某些奇怪的原因,我遇到了小问题。我正在尝试计算每个字符串中的字母数量并带回最高数量。以下是该文件的示例。

@line =

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

我尝试做的是对行中的每个单独元素进行计数的哈希,但由于某种原因,它不断为我提供每个单独氨基酸的计数。我希望输出是:

M 35
S 32
I 28

【问题讨论】:

  • foreach 不会遍历字符串中的字符。
  • 这与您之前的问题几乎相同:Selecting highest count of element except when…
  • @Miller 我知道这很相似,但我无法取得进展并遇到了障碍。尝试调试脚本
  • perl 中的字符串不是字符数组,它们是基本类型。要获取字符列表,请使用 split(//, $string)
  • @ysth 我也尝试过,但它的行为很奇怪,出于某种原因一直给我单个字符。

标签: perl hash count


【解决方案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
小号 32
我 28 岁

【讨论】:

  • 我只得到第一个元素(M 35)作为输出。将继续修补它以获得结果。感谢您迄今为止的帮助!这很有帮助。也得到了 L 35 作为答案,在我看来,它没有计算每条线,只计算最高线。
  • 如果没有看到您正在运行的确切代码,我无法评论您的代码正在做什么。
  • 得到它的工作,就像添加一个文件句柄一样简单。再次感谢思南!您那里的脚本非常好!
【解决方案2】:

您需要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

【讨论】:

  • 需要每个换行符的最大字母数量,对于给您带来的不便,我们深表歉意,并感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 2017-07-05
  • 1970-01-01
  • 2015-08-01
  • 2020-03-20
  • 1970-01-01
相关资源
最近更新 更多