Human Gene Functions(dp)

题目描述

众所周知,人类基因可以认为是一个基因序列,包含四种核苷酸,分别用A,C,T和G四个字母简单地表示。生物学家对鉴别人类基因并确定他们的功能很感兴趣,因为这对诊断人类疾病和开发新药很有用。……
你的任务是编写一个程序,按以下规则比较两个基因并确定它们的相似程度。
给出两个基因AGTGATG和GTTAG,他们有多相似呢?测量两个基因相似度的一种方法称为对齐。使用对齐方法,可以在基因的适当位置插进空格,让两个基因的长度相等,然后根据基因分值矩阵计算分数。
例如,给AGTGATG插入一个空格,就得到AGTGAT-G;给GTTAG插入三个空格,就得到-GT–TAG。空格用减号(-)表示。现在两个基因一样长了,把这两个字符串对齐:
AGTGAT-G
-GT–TAG
对齐以后,有四个基因是相配的:第二位的G,第三位的T,第六位的T和第八位的G。根据下列基因分值矩阵,每对匹配的字符都有相应的分值。
表示空格对空格是不允许的。上面对齐的字符串分值是:
(-3)+5+5+(-2)+(-3)+5+(-3)+5=9。

数据结构

在这里插入图片描述

int score[5][5] =
{{5, -1, -2, -1, -3},
{-1, 5, -3, -2, -4},
{-2, -3, 5, -2, -2},
{-1, -2, -2, 5, -1},
{-3, -4, -2, -1, 0}};
原矩阵的下标是’A’,‘C’,‘G’,‘T’和’-’,有很多程序采用switch语句转换,这里采用map数组转换:char map[128];
只使用其中5个单元:map[‘A’] = 0; map[‘C’] = 1; map[‘G’] = 2; map[‘T’] = 3; map[’-’] = 4;
两个基因使用字符串表示:char str1[MaxN],str2[MaxN];

动态规划算法的实现

本题类似于最长公共子序列(LCS)问题。
使用gene数组记录动态规划过程中产生的中间结果:int gene[MaxN][MaxN];
gene[i][j]表示基因子串str1[0…i-1]和str2[0…j-1]的分值:
①str1取第i-1个字母,str2取’-’:m1 = gene[i-1][j] + score[map[str1[i-1]]][4];
②str1取’-’,str2取第j-1个字母:m2 = gene[i][j-1] + score[4][map[str2[j-1]]];
③str1取第i-1个字母,str2取第j-1个字母:m3 = gene[i-1][j-1] + score[map[str1[i-1]]][map[str2[j-1]]];

则gene[i][j] = max(m1, m2, m3)。最终结果是gene[first][second]。

边界条件
边界条件就是i或j为0的情况,分3种情况:
(1) 当i=0, j=0时,没有任何基因字母就没有分值,gene[0][0] = 0;
(2) 当i=0时,即为gene [0,1…second] :
for(i = 1 ; i <= second;i++)
gene[0][i] = gene[0][i-1]+score[4][map[str2[i-1]]];
(3) 当j=0时,即为gene [1…first, 0] :
for(i = 1 ; i <= first;i++)
gene[i][0] = gene[i-1][0]+score[map[str1[i-1]]][4];
在这里插入图片描述
代码实现

scanf("%d%s", &first, str1);		//第1个基因信息
scanf("%d%s", &second, str2);	//第2个基因信息
//计算动态规划算法的边界条件
gene[0][0] = 0; 
for(i = 1 ; i <= second;i++) 
 gene[0][i] = gene[0][i-1]+score[4][map[str2[i-1]]];
for(i = 1 ; i <= first;i++) 
 gene[i][0] = gene[i-1][0]+score[map[str1[i-1]]][4];
//求解最优值
int m1,m2,m3;
for(i = 1; i<=first;i++)
 for(j = 1; j<=second; j++)
 {
  m1 = gene[i-1][j]+score[map[str1[i-1]]][4];
  m2 = gene[i][j-1]+score[4][map[str2[j-1]]];
  m3 = gene[i-1][j-1]+score[map[str1[i-1]]][map[str2[j-1]]];
  gene[i][j] = max(m1,max(m2,m3));
 }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值