序列比较

序列比较问题在生物中有很多的应用

问题描述:把一个序列变成另一个序列的最少修改步数。用到动态规划

令A=a1,a2,a3,....an ,B=b1,b2,.....bm是2个字符串,其中字符取自一个有限集合(如英语字母表)。我们想一一改变A的字符变把A变成B.改变有3种

1)插入,把某个字符串插入到字符串

2)删除,从字符串中删除某个字符

3)替换,把字符串中的某个字符替换成另一字符

用A(i)表示a1,a2,a3......ai ; B(i)表示b1,b2.....bi

C(i,j)表示从A(i)变换到B(j)的最小的操作次数

现在要求的是C(n,m)即把A(n)变换到B(m)的最小次数

小于(n,m)的意思是“至少有一个小于其上界且另一个值不大于其上界的所有这样的(i,j)组合”

归纳假设:知道如何求解小于(n,m)问题C(i,j)(0<=i<=n,0<=j<=m)

现在如何是使得A(n)------>B(m)修改的次数最小

有三种选择:

  a、删除A[n]能使得次数最少 则C(n,m)=A(n-1,m)+1
b、插入一个元素等于T[m]次数最少 则C(n,m)=C(n,m-1)+1
c 替换的时候 如果C[m]=A[n] 此时C(n,m)=C(n-1,m-1)
否则 C(n,m)=C(n-1,m-1)+1;
基础的情况的时候,C[0][j]=j(0<j<=m)
C[i][0]=i(0<i<=n)

 

基础情况 C(0,j)=i(0<=j<=m)  C(i,0)=i(0<=i<=n)

如果要保存修改最后一次的变化

//1---delete A[n]
//2--->插入一个B[m];3----替换(没有代价的),没有变化
//4----替换 A[n]被替换为B[m]

// 序列比对.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;
/*动态规划解决序列比较问题
author:surpassgood
问题描述:假设串S[1....n]可以进行删除,插入,替换操作,最后变成
T[1.....m],操作次数假设C(n,m)
怎么样解决使得操作的次数最小

假设  a、删除S[n]能使得次数最少 则C(n,m)=c(n-1,m)+1
b、插入一个元素等于T[m]次数最少 则C(n,m)=c(n,m-1)+1
c 替换的时候 如果C[m]=T[n] 此时C(n,m)=c(n-1,m-1)
否则 C(n,m)=C(n-1,m-1)+1;
基础的情况的时候,C[0][j]=j(0<j<=m)
C[i][0]=i(0<i<=n)


*/
#define N 10
#define M 10
int C[N+1][M+1];
char S[]=" abbc",T[]=" babb";
int modify[N+1][M+1];//1---delete s[n]
//2--->插入一个T[m];3----替换(没有代价的),没有变化
//4----替换 S[n]被替换为T[m]
void prin(int modify[][M+1],int n,int m);//打印做S[n]做了哪些操作
int min1(int x,int y)
{
	return x<y?x:y;
}
int fun(char *S,char *T,int n,int m)//下标从1开始的
{
	int i,j;
	int x,y,z,w,min=0xffff;//x删除的时候 y插入 z替换的时候 w不变化的时候
	//最小值
	int opere;
	
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			/*相应的元素赋值*/
			x=C[i-1][j]+1;
			y=C[i][j-1]+1;
			if(min1(x,y)==x)
			{
				min=x;
				opere=1;

			}else
			{
				min=y;
				opere=2;
			}
			
			if(S[i]==T[j])
			{
				w=C[i-1][j-1];
				if(min>w)
				{
					min=w;
					opere=3;
				}
			}else 
			{
				z=C[i-1][j-1]+1;
				if(min>z)
				{
					min=z;
					opere=4;
				}
			}
			C[i][j]=min;
			modify[i][j]=opere;
			min=0xffff;
			opere=0;
			


		}
	}
	
	prin(C,n,m);

		
	
	cout<<endl;


	return C[n][m];
}
void prin(int C[][M+1],int n,int m)//打印做S[n]做了哪些操作
{
	if(n<0||m<0) return;
	if(m==0&&n==0) return;
	//1---delete s[n]
//2--->插入一个T[m];3----替换(没有代价的),没有变化
//4----替换 S[n]被替换为T[m]
	
	switch (modify[n][m])
	{
	case 1 :
		{prin(C,n-1,m);
		cout<<"delete "<<S[n]<<endl;break;}
	case 2:
		{
			cout<<S[n]<<"--insert-- "<<T[m]<<endl;
			prin(C,n,m-1);
			break;
		}
	case 4:
		{
			
			
			cout<<S[n]<<"被换成"<<T[m]<<endl;
			prin(C,n-1,m-1);
			
			break;
		}
	case 3:
		prin(C,n-1,m-1);break;

	}
	

}


int _tmain(int argc, _TCHAR* argv[])
{
	int i,j;
	for(i=0;i<=N;i++)
		for(j=0;j<=M;j++)
			modify[i][j]=0;
	for(i=0;i<=N;i++)
	{
		C[i][0]=i;
		modify[i][0]=1;//这要注意了,我当时赋值为2 ,发现结果不对,1表示删除
	}
	for(j=0;j<=N;j++)
	{
		C[0][j]=j;
		modify[0][j]=2;
	}
	
	//cout<<fun(S,T,4,4)<<endl;

	cout<<"input the source string 小标从1开始,在你要输入的字符串前加个字符"<<endl;
	cin>>S;
	cout<<"input the destination string 小标从1开始"<<endl;
	cin>>T;
	cout<<"source---->"<<endl;
	for(i=1;i<strlen(S);i++)
	{
	cout<<S[i];
	}
	
	cout<<endl;
	cout<<"-----covert-------"<<endl<<endl;
	cout<<"变化了次数:"<<fun(S,T,strlen(S)-1,strlen(T)-1)<<endl;
	cout<<"-----end-------"<<endl<<endl;
	cout<<"destination---->"<<endl;
	
	for(i=1;i<strlen(T);i++)
	{
	cout<<T[i];
	}
	cout<<endl;
	

	
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值