动态规划之最长子串(LCS)

动态规划问题之最长子串(LCS)


输入两个字符串string1,string2,找出其中重复的最长子串。


选取其中一个字符串,从第一个字符开始与另一个字符串的每个字符比较,相同为1,不同为0,构造第一行。接着第二个字符,最后构建成为一个二维数组。

eg:

string1 = abc
String2 = dbc
得到的二维数组为 :

    0  0  0
    0  1  0
    0  0  1

可以算看最长子串为长度为2 为bc

为了使最后便于得到最长子串 现在如果某位置相同,则让此位置的二维数组的大小为其左上角的值+1

则原二维数组变为:

0 0 0
0 1 0
0 0 2

用一个[1][1]的数组记录数组位置2(数组从0开始) 长度为2 则最大子串为 位置2+1 -长度2起始 到位置2+1 结束

最后为得到最长子串时候有多个 重新遍历了此二维数据

code(java实现)

     public static void main(String argv[]) {
    Scanner scanner = new Scanner(System.in);

    String data1 = scanner.next();
    String data2 = scanner.next();
    byte[] a1 = data1.getBytes();
    byte[] a2 = data2.getBytes();

    int low_l = a1.length > a2.length ? a2.length : a1.length;

    int data[][] = new int[data2.length() > data1.length() ? data1.length() : data2.length()][getMax(data1, data2)];

    int max = 0;
    int max_index[][] = new int[2][3];

    //构造矩阵
    for (int i = 0; i < (data2.length() > data1.length() ? data1.length() : data2.length()); i++) {
        for (int j = 0; j < getMax(data1, data2); j++) {
            if (i < low_l && j < low_l && a1[i] == a2[j]) {
                if (j == 0 || i == 0) {
                    data[i][j] = 1;
                } else {
                    data[i][j] = data[i - 1][j - 1] + 1;
                }
            }
            if (data[i][j] > max) {
                max = data[i][j];
                max_index[0][0] = i;
                max_index[0][1] = max;
            }
        }
    }

    //查找子串
    for (int i = 0; i < (data2.length() > data1.length() ? data1.length() : data2.length()); i++) {
        for (int j = 0; j < getMax(data1, data2); j++) {
            if (data[i][j] == max) {
                System.out.println("最长子串 :" + MaxLcs(data1, i, max) + "   在第一个字符串的第" + (i + 2 - max) + "位开始");
            }
        }
    }
}

//最大值
static int getMax(String data1, String data2) {
    return data1.length() > data2.length() ? data1.length() : data2.length();
}

//得到子串
static String MaxLcs(String data, int index, int end) {
    return data.substring(index + 1 - end, index + 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值