LCS问题

//动态规划(Dynamic programming)的最长公共子序列问题(Longest common subsequence)
//原理参考《算法导论》书
import java.util.Scanner;

public class LCS {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String s1=sc.nextLine();
        String s2=sc.nextLine();
        int len1=s1.length();
        int len2=s2.length();
        int c[][]=new int[len1+1][len2+1];
        int b[][]=new int[len1+1][len2+1];
        for(int i=0;i<=len1;i++){
            for(int j=0;j<=len2;j++){
                if(i==0||j==0){
                    c[i][j]=0;
                }else if(s1.charAt(i-1)==s2.charAt(j-1)){
                    c[i][j]=c[i-1][j-1]+1;
                    b[i][j]=1;//表示左向上箭头
                }else if(c[i-1][j]>=c[i][j-1]){
                    c[i][j]=c[i-1][j];
                    b[i][j]=2;//表示↑
                }else{
                    c[i][j]=c[i][j-1];
                    b[i][j]=3;//表示←
                }
            }
        }
        //直接输出表c,c[i,j]表示Xi和Yj的LCS的长度
        /*
        for(int i=0;i<=len1;i++){
            for(int j=0;j<=len2;j++){
                System.out.print(c[i][j]+" ");
            }
            System.out.println();
        }
        */
        
        //直接输出表b,b[i,j]表示子问题最优解的指向
        /*
        for(int i=0;i<=len1;i++){
            for(int j=0;j<=len2;j++){
                System.out.print(b[i][j]+" ");
            }
            System.out.println();
        }
        */
        
        System.out.println(c[len1][len2]);
        printLCS(b,s1,len1,len2);//调用方法printLCS,打印LCS的元素
        sc.close();
    }
    
    /**
     * 封装一个方法,打印LCS的元素(利用递归过程,逆序依次打印)
     * @param b 子问题最优解的指向
     * @param str 一个输入序列X
     * @param m 输入序列X的长度
     * @param n 输入序列Y的长度
     */
    public static void printLCS(int b[][],String str,int m,int n){
                if(m==0||n==0){
                    return;
                }
                if(b[m][n]==1){
                    printLCS(b,str,m-1,n-1);
                    System.out.print(str.charAt(m-1)+" ");
                }else if(b[m][n]==2){
                    printLCS(b,str,m-1,n);
                }else{
                    printLCS(b,str,m,n-1);
                }//直接用递归,之前用了for循环,一直输出好多元素.....
    }
}

 

posted @ 2017-05-16 09:55  CYTing  阅读(404)  评论(0编辑  收藏  举报