Какой самый быстрый способ подсчитать, сколько раз все элементы в массиве встречаются в строке?
У меня есть строка ($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;
}