Подтвердить что ты не робот

Подсчет количества вхождений строки внутри другой (Perl)

Каков самый быстрый способ подсчета количества раз, когда определенная строка появляется в более крупном? Лучше всего было бы заменить все экземпляры этой строки ничем, вычислить разницу длин и разделить на длину подстроки, но это кажется довольно медленным, и мне нужно проанализировать большие объемы данных.

4b9b3361

Ответ 1

Вы можете захватить строки, а затем подсчитать их. Это можно сделать, применив контекст списка к захвату с помощью ():

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;

Ответ 2

my $string = "aaaabbabbba";
my @count = ($string =~ /a/g);
print @count . "\n";

или

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

Ответ 3

Вы можете использовать глобальное регулярное выражение. Что-то вроде:

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

Ответ 4

Просто для полноты вы можете повторно вызвать функцию индекса в цикле и подсчитать все время, когда он вернул индекс подстроки в строке, и измените начальную позицию. Это позволит избежать использования регулярных выражений, а в моем тестировании выполняется бит быстрее, чем регулярные выражения.

Я адаптировал sub, чтобы сделать это отсюда: 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;
}