Я попытаюсь разобраться с предоставленной очень ограниченной информацией.
Сначала короткая дружеская редакционная статья:
<editorial>
Пожалуйста, научитесь задать хороший вопрос и как быть точным .
Как минимум, пожалуйста:
- Воздерживаться от жаргона, специфичного для предметной области, такого как «мотив» и «тандемный повтор» и «пары оснований», без предоставления ссылок или точных определений;
- Скажите, какова цель и что вы уже сделали;
- Внимание! Предоставьте наглядные примеры ввода и желаемого результата.
Потенциальным помощникам на SO не нужно играть 20 вопросов в комментариях, чтобы понять ваш вопрос! Я потратил больше времени на то, чтобы понять, о чем ты спрашиваешь, чем ответить на него.
</editorial>
Следующая программа генерирует строку из 2 пар символов длиной 5428 пар в массиве из 1000 элементов. Я понимаю, что более вероятно, что вы будете читать их из файла, но это всего лишь пример. Очевидно, вы бы заменили случайные строки вашими фактическими данными из любого источника.
Я не знаю, являются ли 'AT','CG','TC','CA','TG','GC','GG'
, которые я использовал, допустимыми комбинациями базовых пар или нет. (Я проспал биологию ...) Просто отредактируйте пары блоков map
для допустимых пар и замените 7
на количество пар, если вы хотите сгенерировать допустимые случайные строки для тестирования.
Если подстрока в точке offset
имеет 3 различия или меньше, элемент массива (скалярное значение) сохраняется в анонимном массиве в части значения хэша. Ключевой частью хэша является подстрока, которая почти совпадает. Вместо элементов массива значения могут быть именами файлов, ссылками на данные Perl или другими соответствующими ссылками, которые вы хотите связать с вашим мотивом.
Хотя я только что посмотрел на символьные различия между строками, вы можете поместить любую конкретную логику, которую вам нужно посмотреть, заменив строку foreach my $j (0..$#a1) { $diffs++ unless ($a1[$j] eq $a2[$j]); }
на логику сравнения, которая работает для вашей проблемы. Я не знаю, как mismatches/insertions/deletions
представлены в вашей строке, поэтому я оставляю это в качестве упражнения для читателя. Возможно Алгоритм :: Diff или String :: Diff из CPAN?
Легко изменить эту программу, чтобы иметь ввод с клавиатуры для $target
и $offset
или чтобы строка поиска начиналась с конца до конца, а не несколько строк с фиксированным смещением. Еще раз: было не совсем понятно, какова ваша цель ...
use strict; use warnings;
my @bps;
push(@bps,join('',map { ('AT','CG','TC','CA','TG','GC','GG')[rand 7] }
0..5428)) for(1..1_000);
my $len=length($bps[0]);
my $s_count= scalar @bps;
print "$s_count random strings generated $len characters long\n" ;
my $target="CGTCGCACAG";
my $offset=832;
my $nlen=length $target;
my %HoA;
my $diffs=0;
my @a2=split(//, $target);
substr($bps[-1], $offset, $nlen)=$target; #guarantee 1 match
substr($bps[-2], $offset, $nlen)="CATGGCACGG"; #anja example
foreach my $i (0..$#bps) {
my $cand=substr($bps[$i], $offset, $nlen);
my @a1=split(//, $cand);
$diffs=0;
foreach my $j (0..$#a1) { $diffs++ unless ($a1[$j] eq $a2[$j]); }
next if $diffs > 3;
push (@{$HoA{$cand}}, $i);
}
foreach my $hit (keys %HoA) {
my @a1=split(//, $hit);
$diffs=0;
my $ds="";
foreach my $j (0..$#a1) {
if($a1[$j] eq $a2[$j]) {
$ds.=" ";
} else {
$diffs++;
$ds.=$a1[$j];
}
}
print "Target: $target\n",
"Candidate: $hit\n",
"Differences: $ds $diffs differences\n",
"Array element: ";
foreach (@{$HoA{$hit}}) {
print "$_ " ;
}
print "\n\n";
}
Выход:
1000 random strings generated 10858 characters long
Target: CGTCGCACAG
Candidate: CGTCGCACAG
Differences: 0 differences
Array element: 999
Target: CGTCGCACAG
Candidate: CGTCGCCGCG
Differences: CGC 3 differences
Array element: 696
Target: CGTCGCACAG
Candidate: CGTCGCCGAT
Differences: CG T 3 differences
Array element: 851
Target: CGTCGCACAG
Candidate: CGTCGCATGG
Differences: TG 2 differences
Array element: 986
Target: CGTCGCACAG
Candidate: CATGGCACGG
Differences: A G G 3 differences
Array element: 998
..several cut out..
Target: CGTCGCACAG
Candidate: CGTCGCTCCA
Differences: T CA 3 differences
Array element: 568 926