动态规划之LCS最长公共子序列和最长公共子串


一、最长公共子序列



最长公共子序列的结构有如下表示:

设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>,则:

  1. 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
  2. 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;
  3. 若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。

package dynamic_programming;

public class lcs0831 {
public static void main(String[] args)
{
	String A="ABCDuiop";
	String B="CBCEuiop";
	int[][] strslen=new int[A.length()][B.length()];
	for(int i=0;i<A.length();i++)
	{
		strslen[i][0]=0;
	}
	for(int j=0;j<B.length();j++)
	{
		strslen[0][j]=0;
	}
	if(A.charAt(0)==B.charAt(0))
	{
		strslen[0][0]=1;
	}
	else
	{
		strslen[0][0]=0;
	}
	for(int i=1;i<A.length();i++)
	{
		for(int j=1;j<B.length();j++)
		{
			if(A.charAt(i)==B.charAt(j))
			{
				strslen[i][j]=strslen[i-1][j-1]+1;
                                System.out.print(A.charAt(i)); 
                        }
			else
			{
			  strslen[i][j]=Math.max(strslen[i-1][j], strslen[i][j-1]);	
			}
		}
	}
	System.out.print(strslen[A.length()-1][B.length()-1]);
}
}

输出为:BCuiop6



二、最长公共子串


package dynamic_programming;

public class LCSProblem {
public static void main(String[] args)
{
	String A="ABCDuiopc";
	String B="CBCEuiopb";
	StringBuilder commsStr=new  StringBuilder();
	int bigest=0;
	int x = 0,y=0;
	int[][] strslen=new int[A.length()][B.length()];
    for(int i=0;i<A.length();i++)
    {
    	strslen[i][0]=0;
    }
    for(int j=0;j<B.length();j++)
    {
    	strslen[0][j]=0;
    }
    if(A.charAt(0)==B.charAt(0))
      strslen[0][0]=1;
    else
    {
    	strslen[0][0]=0;
    }
    for(int i=1;i<A.length();i++)
    {
    	for(int j=1;j<B.length();j++)
    	{
    		if(A.charAt(i)==B.charAt(j))
    		{
    			strslen[i][j]=strslen[i-1][j-1]+1;
    			if(bigest<strslen[i][j])
    			{
    				bigest=strslen[i][j];
    				 x=i;  //x,y存储子串最后一个字母
    			         y=j;
    			}
    		}
    		else
    		{
    			strslen[i][j]=0;   //与最长公共子序列不同点:如果两个字母不相等,则赋值为0
    		}
    	}
    }
    System.out.println(bigest);	
    while(x>=0&&y>=0)
    {
    	if(A.charAt(x)==B.charAt(y))
    	{
    		commsStr.append(A.charAt(x));
    		x--;
    		y--;
    	}
    	else
    	{
    		break;
    	}
    }
    System.out.println(commsStr.reverse());
}
}

输出结果为:

4
uiop



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值