最长公共子序列问题

问题描述: LCS是Longest Common Subsequence的缩写,即最长公共子序列。一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列

举例说明:比如,对于char x[]="aabcd";有顺序且相互相邻的aabc是其子序列,有顺序但是不相邻的abd也是其公共子序列。即,只要得出序列中各个元素属于所给出的数列,就是子序列。再加上char y[]="12abcabcd";对比出才可以得出最长公共子序列abcd。

array[i][j] -- 表示子串s1[0...i](数组长度为n)和子串s2[0...j](数组长度为m)的最长公共子序列

当s1[i] == s2[j]时,array[i][j] = array[i-1][j-1] + 1                                    公式1;

否则,array[i][j] = max(array[i-1][j], array[i][j-1])                                     公式2;
 


    /**
     *
     * @param s1       第一个字符序列
     * @param length1  第一个字符序列的长度
     * @param s2       第二个字符序列 
     * @param length2  第二个字符序列的长度
     */

    public static void getlcs(String s1,int length1,String s2,int length2)
    {
        char[] x = s1.toCharArray();
        char[] y = s2.toCharArray();
        int[][] array = new int[length1+1][length2+1];
        for(int i=0;i<length1+1;i++){                // 将二维列表的第一例填为零
            array[i][0]=0;
        }
        for(int j=0;j<length2+1;j++){                // 将二维列表的第一行填为零
            array[0][j]=0;
        }
        for(int i=0;i<length1;i++){
            for(int j=0;j<length2;j++){
                if(x[i]==y[j]){
                    array[i+1][j+1]=array[i][j]+1;    //  此问题的第一个公式

                }else {
                    array[i+1][j+1]=max(array[i+1][j],array[i][j+1]);  //此问题的第二个公式
                }
            }
        }
        // 打印二维表格
        for(int i=0;i<length1+1;i++){
            for(int j=0;j<length2+1;j++){
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }

        Stack<Character> s = new Stack<Character>();     //  用栈从后向前存储最长子序列,打印出来正好是正向最长公共子序列
        while (length1>0 && length2>0){
            if (x[length1-1]==y[length2-1]){
                s.push(x[length1-1]);
                length1--;
                length2--;
            }else if(array[length1-1][length2]>array[length1][length2-1]){
                length1--;
            }else {
                length2--;
            }
        }

        while (!s.empty()){
            System.out.print(s.pop());//   打印最长公共子序列
        }
    }
}

  public static int max(int a, int b){//比较(a,b),输出大的值
        return (a > b)? a : b;
    }

转载自https://blog.csdn.net/qbyhqp/article/details/82050535

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值