Моей первой мыслью было глобальное сопоставление в скалярном контексте с настройкой pos () для резервного копирования.Таким образом, мне нужно сканировать строку только один раз для всех димеров (тогда как другие ответы пока сканируют последовательность один раз для каждого димера).Я тоже поддерживаю хэши;один для всего и один для последовательности.Я использую специальную переменную $.
, которая содержит текущий номер строки ввода для обозначения последовательности:
use Data::Printer;
while( <DATA> ) {
while( /\G([ATGC]{2})/g ) {
$total{$1}++;
$by_sequence{$.}{$1}++;
pos() = pos() - 1
}
}
p( %total );
p( %by_sequence );
То же самое с substr потребовало немного больше работы, потому чтоЯ не мог ограничить подстроку только символами, которые имели значение.Я должен был обратить внимание на новые строки и нечетные числа в конце:
use Data::Printer;
LINE: while( <DATA> ) {
chomp;
my $pos = 0;
SUB: while( my $sub = substr( $_, $pos, 2 ) ) {
last SUB unless 2 == length $sub;
$total{$sub}++;
$by_sequence{$.}{$sub}++;
$pos++;
}
}
p( %total );
p( %by_sequence );
Вывод из Data :: Printer очень хорош.Я использую его в предпочтении Data :: Dumper , так как я узнал об этом на YAPC :: Brasil.(И, кстати, его автор будет в YAPC :: NA в Мэдисоне в этом году , чтобы поговорить об этом ):
{
AA 101,
AC 215,
AG 268,
AT 106,
CA 286,
CC 388,
CG 201,
CT 310,
GA 239,
GC 376,
GG 369,
GT 168,
TA 61,
TC 206,
TG 317,
TT 73
}
{
1 {
AA 9,
AC 3,
AG 8,
AT 8,
CA 11,
CC 12,
CG 3,
CT 11,
GA 5,
GC 9,
GG 8,
GT 6,
TA 2,
TC 13,
TG 10,
TT 7
},
2 {
AA 68,
AC 177,
AG 219,
AT 80,
CA 230,
CC 329,
CG 168,
CT 264,
GA 195,
GC 316,
GG 317,
GT 146,
TA 50,
TC 169,
TG 271,
TT 54
},
3 {
AA 24,
AC 35,
AG 41,
AT 18,
CA 45,
CC 47,
CG 30,
CT 35,
GA 39,
GC 51,
GG 44,
GT 16,
TA 9,
TC 24,
TG 36,
TT 12
}
}