IT笔面试之最长公共子序列

先介绍LCS问题的性质:记Xm={x0, x1,…xm-1}Yn={y0,y1,…,yn-1}为两个字符串,而Zk={z0,z1,…zk-1}是它们的LCS,则:

1.       如果xm-1=yn-1,那么zk-1=xm-1=yn-1,并且Zk-1Xm-1Yn-1LCS
2.       如果xm-1≠yn-1,那么当zk-1≠xm-1ZXm-1YLCS
3.       如果xm-1≠yn-1,那么当zk-1≠yn-1ZYn-1XLCS

公式: 

            0                                if  i<0 or j<0
c[i,j]=       c[i-1,j-1]+1                     if  i,j>=0 and xi=xj
            max(c[i,j-1],c[i-1,j])            if  i,j>=0 and xi≠xj
 

注意与最长公共子串的区别:字串是连续的,子序列可不连续。

http://my.oschina.net/gaosheng/blog/308853

 
#include <cstring>
#include <cstdio>
#define M 1010
 
int LCS(char* str1, char* str2)
{
    if(!str1 || !str2)
        return 0;
 
    int length_1 = strlen(str1);
    int length_2 = strlen(str2);
 
    if(!length_1 || !length_2)
        return 0;
 
    int m[length_1+1][length_2+1];
 
    //初始化边界,过滤掉0的情况
    for (int i = 0; i <= length_1; i++)
        m[i][0] = 0;
 
 
    for (int j = 0; j <= length_2; j++)
        m[0][j] = 0;
 
 
    //填充矩阵
    for (int i = 1; i <= length_1; i++)
    {
        for (int j = 1; j <= length_2; j++)
        {
            //相等的情况
            if (str1[i - 1] == str2[j - 1])
                m[i][j] = m[i - 1][j - 1] + 1;
            else
            {
                //比较“左边”和“上边“,根据其max来填充
                if (m[i - 1][j] >= m[i][j - 1])
                    m[i][j] = m[i - 1][j];
                else
                    m[i][j] = m[i][j - 1];
            }
        }
    }
    return m[length_1][length_2];
}
 
int main()
{
    char str1[M],str2[M];
    memset(str1,0,sizeof(M));
    memset(str2,0,sizeof(M));
 
    printf("请输入字符串str1:");
    scanf("%s", str1);
 
    printf("请输入字符串str2:");
    scanf("%s", str2);
 
    printf("%d\n",LCS(str1,str2));
    return 0;
}


你可能感兴趣的:(IT笔面试之最长公共子序列)