回文序列
遗传学上讲的回文序列指的是双链DNA或RNA分子中的特定的核苷酸片段,该片段在其中一条链上按5’到3’读取的序列与其互补链上按相同的5’到3’读取的序列一致。回文序列能够形成发夹。
回文序列广泛存在于各种生物体基因组中,主要和转录终止有关,也是限制性内切酶酶切位点,还参与DNA复制等生命活动。
回文序列在分子生物学中起着重要的作用。许多限制性内切酶能识别特定的回文序列并切割它们。比如,限制性内切酶EcoR1识别以下回文序列:
5’- G A A T T C -3’
3’- C T T A A G -5’
给出你一段脱氧核苷酸单链碱基序列,输出该序列最长回文子序列的互补链序列。
Input
输入数据有多组,第一行是一个正整数T,(0<T<100),代表有T组数据,每组测试数据包含一条单链脱氧核苷酸碱基序列S,(S是一个长度不超过100的字符串,且S仅由大写字母“A,G,C,T”组成)
Output
找出该脱氧核苷酸碱基序列的最长回文子序列,并输出最长回文序列的互补碱基序列(保证最长回文序列长度大于等于2,若存在相同长度的回文序列,输出更靠前的那一个)
Sample Intput
3
GAATTC
GATCCGTA
ATGCATGCGCGC
Sample Output
CTTAAG
CTAG
TACGTA
思路:
由于碱基配对的特殊性,满足要求的序列长度一定为偶数。遍历整个字符串,枚举任意相邻两位并且满足回文要求的序列为回文序列的中心,然后以此为中心,每次左右同时增添一位,直到不满足回文序列要求为止,记录这个序列的初始位置和下标。遍历所有位置,比较得出最长回文序列的起始位置下标和序列长度,最后输出该序列的碱基互补序列。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char s[110],b[110];
int t,maxx,locate;
int main()
{
scanf("%d",&t);
while(t--)
{
maxx=0;
scanf("%s",s);
int l=strlen(s);
for(int i=0; i<l; i++){
if(s[i]=='A') b[i]='T';
if(s[i]=='G') b[i]='C';
if(s[i]=='C') b[i]='G';
if(s[i]=='T') b[i]='A';
}
for(int i=1; i<l; i++)
for(int k=i-1,j=i; k>=0&&s[k]==b[j]&&s[j]==b[k]; k--,j++)
if((i-k)*2>maxx){
maxx=(i-k)*2;
locate=k;
}
for(int i=locate; i<locate+maxx; i++)
printf("%c",b[i]);
printf("\n");
}
return 0;
}