最长公共子串 Longest Common SubString

这篇博客探讨了如何使用动态规划找到两个字符串之间的最长公共子串。区别于子序列,子串要求字符必须连续。文章介绍了动态规划的思路,当字符匹配时,二维数组值为前一位置加1,不匹配时则置为0。最终通过二维数组信息可获取最长公共子串的长度及内容。
摘要由CSDN通过智能技术生成

给定两个字符串,求出它们之间最长的相同子字符串的长度。

子串要求字符必须是连续的,但是子序列就不是这样了。。

子序列跟子串的求法类似,都是使用动态规划的思想,s1每次增加一个字符,看与s2当前位置的字符是不是相同,如果相同做相应的处理,如果不同,做另外的处理。

子序列的处理方式:

相同的情况下,该二维数组的位置等于[i-1][j-1]+1

不同的情况下,该二维数组的位置等于MAX(d[i-1][j],d[i][j-1])

下面描述下子串的求法。

最长公共子串,要求字符是连续的。那么在[s1每次增加一个字符,看与s2当前位置的字符是不是相同]

相同的情况下,二维数组的位置等于[i-1][j-1]+1,

不同的情况下,二维数组的位置等于0,最后再查看二维数组的信息即可得到最长公共子串的长度,同时可以回溯二维数组得到最长公共字串的内容。

package other;

import util.ArrayUtil;

public class LongestCommonSubString {

    public static void main(String[] args) {

        longestCommonSubString("abcdefg","hbcsefgk");
    }

    public static void longestCommonSubString(String strX,String strY){
        int pos_x = 0,pos_y = 0;
        int lenX = strX.length();
        int lenY = strY.length();
        System.out.println("abcdef:"+lenX+";hbcsefgk:"+lenY);
        int[][] L = new int[lenX+1][lenY+1];
        int result = 0;
        for(int i=1;i<=lenX;i++){
            for(int j=1;j<=lenY;j++){
                if(strX.charAt(i-1)==strY.charAt(j-1)){
                    L[i][j] = L[i-1][j-1]+1;
                     if (L[i][j] > result) {  
                            result = L[i][j];  
                            pos_x = i;// 记录下最大长度在二维数组中的位置  
                            pos_y = j;  
                        }  
                }else{
                    L[i][j] = 0;
                }
            }
        }
        print(L);
        System.out.println("最长公共子串 长度:"+result);
        System.out.println("=============================");
        // 输出最长子串  
        StringBuilder sb = new StringBuilder();  
        while (L[pos_x][pos_y] != 0) {  
            sb.append(strX.charAt(pos_x - 1));  
            pos_x--;  
            pos_y--;  
        }  
        System.out.println(sb.reverse());   
    }

    public static void print(int[][] arr){
        for (int i = 0; i < arr[0].length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[j][i]+"  ");
            }
            System.out.println();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值