Какой самый быстрый способ подсчитать, сколько раз все элементы в массиве встречаются в строке?

У меня есть строка ($info) это выглядит примерно так:

$info = "Complete1:1,ATTCGGCTAGGGCTAGCTAGCTAG,Complete1:2,ATTTGAGAGGGATCGCGCCAT,..."

И массив (@codes) это выглядит примерно так:

@codes = ("ACTTTCGGGGCATCGGATCG", "ATTGCATGGGCATGGCATGGCATG", "ACGGGATGGGCATGCTAG",...);

Массив @codes содержит некоторые элементы, которые соответствуют (1 или более) частям $info и некоторые элементы, которые не совпадают $info совсем.

Каков был бы самый быстрый способ подсчитать количество раз все элементы в @codes соответствует строке $info? Спасибо!

2 ответа

Для этого на ум приходят два подхода:

my $pat = join '|', map quotemeta, @codes;
my $re = qr/,(?:$pat),/;

for my $info (...) {
   my $padded_info = ",$info,";
   my $count; ++$count while $padded_info =~ /$re/g;
   ...
}

или же

my %codes = map { $_ => 1 } @codes;

for my $info (...) {
   my $count = grep $codes{$_}, split /,/, $info;
   ...
}

Я выложил код, как будто несколько строк проверяются на код в @codes, Повторное использование рассчитанных значений является источником реальной экономии.

Я оставлю вам бенчмаркинг и микрооптимизацию, поскольку это будет зависеть от ваших данных и модели использования.

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

my %results;

for my $code (@codes) {
    my $count = () = $info =~ /$code/g;
    $results{$code} = $count;
}
Другие вопросы по тегам