文字列内のFとTの数を数える次のPerlスクリプトがあります。
my $str = "GGGFFEEIIEETTGGG";
my $ft_count = 0;
$ft_count++ while($str =~ m/[FT]/g);
print "$ft_count\n";
カウントを取得する(つまり、2行目と3行目を組み合わせる)より簡潔な方法はありますか?
文字列内のFとTの数を数える次のPerlスクリプトがあります。
my $str = "GGGFFEEIIEETTGGG";
my $ft_count = 0;
$ft_count++ while($str =~ m/[FT]/g);
print "$ft_count\n";
カウントを取得する(つまり、2行目と3行目を組み合わせる)より簡潔な方法はありますか?
my $ft_count = $str =~ tr/FT//;
perlopを参照してください。
REPLACEMENTLISTが空の場合、SEARCHLISTが複製されます。この後者は、クラス内の文字を数えるのに役立ちます…
$cnt = $sky =~ tr/*/*/; # count the stars in $sky
$cnt = tr/0-9//; # count the digits in $_
ベンチマークは次のとおりです。
use strict; use warnings;
use Benchmark qw( cmpthese );
my ($x, $y) = ("GGGFFEEIIEETTGGG" x 1000) x 2;
cmpthese -5, {
'tr' => sub {
my $cnt = $x =~ tr/FT//;
},
'm' => sub {
my $cnt = ()= $y =~ m/[FT]/g;
},
};
レートtrm レートmtr m 108 / s---99% tr 8118 / s 7440%-
32WindowsXP上のActiveStatePerl5.10.1.1006を使用。
違いはスターカーのようです
C:\ Temp> c:\ opt \ skeleton-5.12.1 \ perl \ bin \ perl.exe t.pl レートmtr m 88.8 / s--100% tr 25507 / s 28631%-
はい、CountOfシークレット演算子を使用できます:
my $ft_count = ()= $str =~ m/[FT]/g;
「m」演算子に/gフラグがあり、リストコンテキストで実行されると、一致するサブ文字列のリストが返されます。したがって、これを行う別の方法は次のようになります。
my @ft_matches = $str =~ m/[FT]/g;
my $ft_count = @ft_matches; # count elements of array
しかし、それはまだ2行です。それを短くすることができる別の奇妙なトリック:
my $ft_count = () = $str =~ m/[FT]/g;
「()=」は「m」をリストコンテキストに強制します。N個の要素を持つリストをゼロ変数のリストに割り当てても、実際には何も起こりません。ただし、この代入式がスカラーコンテキスト($ ft_count = ...)で使用される場合、右の "="演算子は、右側から要素の数を返します。これはまさに必要な数です。
これは最初に遭遇したときは信じられないほど奇妙ですが、「=()=」イディオムは「リストコンテキストで評価してからリストのサイズを取得する」ために知っておくと便利なPerlのトリックです。
注:大きな文字列を処理するときに、これらのどれがより効率的であるかについてのデータはありません。実際、その場合は元のコードが最適だと思います。
次のように、2、3、4行目を1つに組み合わせることができます。
my $str = "GGGFFEEIIEETTGGG";
print $str =~ s/[FT]//g; #Output 4;