最长公共子串和最长公共子序列

  最长公共子串:在两个字符串中找到一个最长的公共子串,要求子串在原串中是连续的。

  最长公共子序列:在两个字符串中找到一个最长的公共子串,要求子串在原串中是连续的。

  用矩阵描述起来,显而易见,由于本人描述能力较差,现推荐一篇博文。

  http://www.cnblogs.com/zhangchaoyang/articles/2012070.html

  以下是本人根据该文章中的讲解所实现的代码:

#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 1000

/*
最长公共字串(连续)
21232523311324
312123223445
*/
int lcs(char *str1, char *str2)
{
    int i, j;
    int nMaxLen = 0;
    int nPosOfMaxS = 0;
    int nLen1 = strlen(str1);
    int nLen2 = strlen(str2);
    int nTmpArray1[MAX_STR_LEN];
    int nTmpArray2[MAX_STR_LEN];
    for(i=0; i<MAX_STR_LEN; ++i)
    {
        nTmpArray1[i] = 0;
        nTmpArray2[i] = 0;
    }
    for(i=0; i<nLen1; ++i)
    {
        for(j=0; j<nLen2; ++j)
        {
            if(str1[i] == str2[j])
            {
                if(j>0)
                {
                    nTmpArray2[j] = nTmpArray1[j-1] + 1;
                }
                else
                {
                    nTmpArray2[j] = 1;
                }
                if(nTmpArray2[j] > nMaxLen)
                {
                    nMaxLen = nTmpArray2[j];
                    nPosOfMaxS = j;
                }
            }
            else
            {
                 nTmpArray2[j] = 0;
            }
        }
        memcpy(nTmpArray1, nTmpArray2, MAX_STR_LEN);
    }
    str2[nPosOfMaxS+1] = 0;
    printf("%d %d\n", nPosOfMaxS, nMaxLen);
    printf("%s\n", str2 + nPosOfMaxS-nMaxLen +1);
    return 0;
}
/*
最长公共子序列(非连续)
GCCCTAGCG
GCGCAATG
*/
int PrintRes(char *str1, int *res, int pos, int maxlen)
{
    if(maxlen == 1)
    {
        printf("%c", str1[pos]);
        return 0;
    }
    //printf("[%d][%d]\n", __LINE__, pos);
    PrintRes(str1, res, res[pos], maxlen-1);
    printf("%c", str1[pos]);
    return 0;
}
int LCS(char *str1, char *str2)
{
    int i, j;
    int nMaxLen = 0;
    int nPosOfMaxS = 0;
    int nTmpMax = 0;
    int nLen1 = strlen(str1);
    int nLen2 = strlen(str2);
    int nTmpArray1[MAX_STR_LEN];
    int nTmpArray2[MAX_STR_LEN];
    int nResArray[MAX_STR_LEN];
    for(i=0; i<MAX_STR_LEN; ++i)
    {
        nTmpArray1[i] = 0;
        nTmpArray2[i] = 0;
        nResArray[i] = 0;
    }
    for(i=0; i<nLen1; ++i)
    {
        nResArray[i] = nPosOfMaxS;
        for(j=0; j<nLen2; ++j)
        {
            nTmpArray2[j] = 0;
            //左上
            if(str1[i]==str2[j] && j>0)
            {
                nTmpArray2[j] = nTmpArray1[j-1] + 1;
            }
            else if(j > 0)
            {
                nTmpArray2[j] = nTmpArray1[j-1];
            }
            else if(str1[i] == str2[j])
            {
                nTmpArray2[j] = 1;
            }
            //
            if(j>0 && nTmpArray2[j-1]>nTmpArray2[j])
            {
                nTmpArray2[j] = nTmpArray2[j-1];
            }
            //
            if(i>0 && nTmpArray1[j]>nTmpArray2[j])
            {
                nTmpArray2[j] =  nTmpArray1[j];
            }
            //printf("%d %d %d %d %d\n", __LINE__, i, j, nTmpArray2[j], nResArray[i]);
            if(nTmpArray2[j]>nMaxLen)
            {
                
                nMaxLen = nTmpArray2[j];
                nPosOfMaxS = i;
                //printf("%d %d %d\n", __LINE__, nMaxLen, i);
            }
        }
        memcpy(nTmpArray1, nTmpArray2, MAX_STR_LEN);
    }
    PrintRes(str1, nResArray, nPosOfMaxS, nMaxLen);
    printf("\n");
    return 0;
}

int main()
{
    char str1[MAX_STR_LEN];
    char str2[MAX_STR_LEN];
    scanf("%s", str1);
    scanf("%s", str2);
    lcs(str1, str2);
    LCS(str1, str2);
    return 0;
}

  在最长公共子序列中,我的结果和该文章的讲解不同,但长度是一样的。由于我们以不同的终点开始递归输出,导致了不同的结果。

posted on 2012-08-29 16:36  favourmeng  阅读(1639)  评论(0编辑  收藏  举报

导航