最长公共子串----不是子序列, 是子串

本文介绍了一种求解最长公共子串问题的算法,并通过两个不同遍历方向的方法进行了实现。示例代码展示了如何找到两个字符数组之间的最长公共子串。
 


import java.util.ArrayList;
import java.util.List;

/**
 * 最长公共子串,注意不是最长公共子序列
 * 子串是substr是原串连续的一部门, 子序列是可以不连续的
 *
 * @author liuyang
 *
 */
public class MaxCommonSubstr {
 
 public static void main(String[] args) {
  char[] a = {'a','c','e','h','p'};
  char[] b = {'b','e','h','k','p'};
  //最长共公告子串的答案就是eh   如果是最长公共子序列,答案就是ehp
  System.out.println("\n"+LC_Str2(a, b));
  
  System.out.println();
  
  System.out.println("\n"+LC_Str(a, b));
 }
 
 public static int LC_Str(char[] a,char[] b){
  
  int max = 0;
  int ea = -1;
  int eb =-1;
  
  int[][] c = new int[a.length+1][b.length+1];//之所以每一维多1,是留着边界条件用的,数组元素值默认就是0;
  //c[i+1][j+1]表示以a[i] b[i]为结尾的最长公共子串的长度
  
  for(int i = 0;i<a.length;i++){
   for(int j=0;j<b.length;j++){
    if(a[i]==b[j])
     c[i+1][j+1]= 1+c[i][j];
    if(c[i+1][j+1] > max){
     max = c[i+1][j+1];
     ea = i;
     eb = j;
    }
   }
  }
  
  List result = new ArrayList();
  for(int i = ea, j = eb;i>=0&&j>=0;i--,j--){
   if(a[i]==b[j])
    result.add(a[i]);
   else
    break;
  }
  for(int i = result.size()-1;i>=0;i--)
   System.out.print(result.get(i)+" ");
  
  return max;
 }
 
 public static int LC_Str2(char[] a,char[] b){
  
  int max = 0;
  int ea = -1;
  int eb =-1;
  
  int[][] c = new int[a.length+1][b.length+1];//之所以每一维多1,是留着边界条件用的,数组元素值默认就是0;
  //c[i][j]表示以a[i] b[i]为开头的最长公共子串的长度
  
  for(int i = a.length-1;i>=0;i--){
   for(int j=b.length-1;j>=0;j--){
    if(a[i]==b[j])
     c[i][j]= 1+c[i+1][j+1];
    if(c[i][j] > max){
     max = c[i][j];
     ea = i;
     eb = j;
    }
   }
  }
  
  for(int i = ea, j = eb;i<a.length&&j<b.length;i++,j++){
   
   if(a[i]==b[j])
    System.out.print(a[i]+" ");
   else
    break;
  }
  
  return max;
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值