最长公共子序列

最长公共子序列问题( Longest Common Subsequence problem,LCS) 是求两个给定序列X= {x1,x2, ... ,xn}与Y= {y1,y2,...,yn} 最长公共子序列的问题。
如果序列z同时为X和y的子序列,那么Z就称为X与Y的公共子序列。举个例子,设X= {a,b,c,b,d,a,b}、Y= {b,d,c,a,b,a},那么序列{b,.c,a} 就是X与Y的公共子序列。但是,序列{b,c,a} 并不是x与Y的最长公共子序列。因为这个序列的长度为3,而X与y之间还存在长度为4 的公共子序列{b,c,b,a}。由于没有长度大于等于5 的公共子序列,所以{b,c,b,a} 就是x与y的最长公共子序列之一。
请编写一个程序,对给定的两个字符串x、Y输出最长公共子序列z 的长度。给定字符串仅由英文字母构成。
输入 给定多组数据。第1行输入数组组数q。接下来的2 x q 行输人数据组,每组数据包含X、Y共2个字符串,每个字符串占1行。
输出 输出每组X、Y的最长公共子序列Z的长度,每个长度占1行。
限制 1 1 若某组数据中X或Y的长度超过100,则q不超过20。


图片发自App

代码:

int lcs(String str1, String str2) {  
    int len1 = str1.length();  
    int len2 = str2.length();  
    int c[][] = 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 (str1.charAt(i-1) == str2.charAt(j-1)) {  
                c[i][j] = c[i-1][j-1] + 1;  
            } else {  
                c[i][j] = max(c[i - 1][j], c[i][j - 1]);  
            }  
        }  
    }  
    return c[len1][len2];  
} 

若数组太大无法开下,则用滚动数组

char a[H];//正序  
char b[H];//逆序  
int c[3][H]; //记录子序列的长度最大值   此处用到了滚动数组 如果开串c[h][h]会超内存(MLE),或改为 short int c[H][H]  
  
int LCS(int m,int n){//求出最长公共子序列的长度  
  
    for(int i=0;i<=2;i++){  
       c[i][0]=0;  
    }  
  
    for(int j=0;j<=n;j++){  
       c[0][j]=0;  
    }  
  
    for(int i=1;i<=m;i++){  
        for(int j=1;j<=n;j++){  
            if(a[i]==b[j])  
                c[i%2][j]=c[(i-1)%2][j-1]+1;  
            else{  
                c[i%2][j]=max(c[(i-1)%2][j],c[i%2][j-1]);  
            }  
        }  
    }  
  
     return c[m%2][n];  
}  

你可能感兴趣的:(最长公共子序列)