web-dev-qa-db-ja.com

別の文字列内での文字列の出現回数のカウント(Perl)

特定の文字列がより大きな文字列に出現する回数をカウントする最も速い方法は何ですか?私の最善の推測は、その文字列のすべてのインスタンスを何も置き換えず、長さの差を計算し、部分文字列の長さで除算することですが、それはかなり遅いようで、大量のデータを分析する必要があります。

34
ronash

文字列をキャプチャしてからカウントできます。 ()を使用してキャプチャにリストコンテキストを適用することで実行できます。

my $x = "foo";
my $y = "foo foo foo bar";
my $c = () = $y =~ /$x/g;  # $c is now 3

配列にキャプチャして、配列をカウントすることもできます。同じ原則、異なる手法:

my @c = $y =~ /$x/g;
my $count = @c;
63
TLP
my $string = "aaaabbabbba";
my @count = ($string =~ /a/g);
print @count . "\n";

または

my $count = ($string =~ s/a/a/g);
15
Brian Roach

グローバル正規表現を使用できます。何かのようなもの:

my @matches = $bigstring =~ /($littlestring)/g;
my $count = @matches;
9
MattLBeck

完全を期すために、ループ内でインデックス関数を繰り返し呼び出して、文字列内の部分文字列のインデックスを返した回数をすべてカウントし、開始位置を変更できます。それは正規表現の使用を避け、私のテストでは正規表現ソリューションよりも少し高速です。

私はここからそれを行うためにサブを適応させました: http://www.misc-Perl-info.com/Perl-index.html

sub occurrences {

    my( $x, $y ) = @_;

    my $pos = 0;
    my $matches = 0;

    while (1) {
        $pos = index($y, $x, $pos);
        last if($pos < 0);
        $matches++;
        $pos++;
    }   

    return $matches;
}
5
Matthew Lock