获得最长公共子串问题


//获得最长公共子串问题
public class MaxSameLenSequen{
	
    //构建动态规划表
    public static int[][]getDp(char[]str1,char[]str2)
    {
      //(dp[i][j]的含义i,j作为最后一个字符,公共子串有多长)
      int[][]dp=new int[str1.length][str2.length];
      //第一行的计算
      for(int i=0;i<str2.length;i++)
      {
      	if(str1[0]==str2[i])
      	{
      		dp[0][i]=1;
      	}

      }
      //第一列的计算
      for(int j=1;j<str1.length;j++)
      {
      	if(str1[j]==str2[0])
      	{
      		dp[j][0]=1;
      	}
      }
      //其他位置的计算
      for(int i=1;i<str1.length;i++)
      {
      	for(int j=1;j<str2.length;j++)
      	{
      		if(str1[i]==str2[j])
      		{
      			dp[i][j]=dp[i-1][j-1]+1;
      		}
      	}
      }
      return dp;
    }

    //获得最长公共子串(时间复杂度O(m*n),空间复杂度O(M*n))
    public static String MaxSameLen(String str1,String str2)
    {
          if(str1==null||str2==null||str1.equals("")||str2.equals(""))
          {
          	return "";
          }
          char[]ch1=str1.toCharArray();
          char[]ch2=str2.toCharArray();
          int[][]dp=getDp(ch1,ch2);
          int end=0;
          int max=0;
          for(int i=0;i<ch1.length;i++)
          {
          	for(int j=0;j<ch2.length;j++)
          	{
          		if(dp[i][j]>max)
          		{
          			end=i;
          			max=dp[i][j];
          		}
          	}
          }
          return str1.substring(end-max+1,end+1);
           
    }
    //**************************************************************
   //获得最长公共子串(对角线解法)(时间复杂度O(m*n),空间复杂度O(1))
    public static String MaxSameLen02(String str1,String str2)
    {
    	if(str1==null|str2==null||str1.equals("")||str2.equals(""))
    	{
    		return "";
    	}
        char[]ch1=str1.toCharArray();
        char[]ch2=str2.toCharArray();
        int row=0;            //斜线开始的位置的行
        int col=ch2.length-1; //斜线开始的位置的列
        int max=0;            //记录最大的长度
        int end=0;            //最大长度更新时,记录子串的结尾位置
        while(row<ch1.length)
        {
        	int i=row;
        	int j=col;
        	int len=0;
        	//从(i,j)开始向右下方遍历
        	while(i<ch1.length&&j<ch2.length)
        	{
        		if(ch1[i]!=ch2[j])
        		{
        			len=0;
        		}
        		else{
        			len++;
        		}
        		//记录最大值
        		if(len>max)
        		{
                    end=i;
        			max=len;
        		}
        		//斜线位置计算
        		i++;
        		j++;
        	}

        	if(col>0)
        	{
        		col--;//斜线开始的位置的列向左下方移动
        	}
        	else{
        		row++;//斜线开始的行从向下移动
        	}
        }

          return str1.substring(end-max+1,end+1);

    }
 
	public static void main(String[]args)
	{
           String str1="abcde";
           String str2="bebcd";
           //System.out.println(str1.substring(1,3));
           System.out.println(MaxSameLen(str1,str2));
           System.out.println(MaxSameLen02(str1,str2));


	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值