最长公共子串问题 LCS


/*
题目描述:最长公共字串问题(LCS)。如果字符串一的所有字符按其顺序出现在另外一个字符串二中,
则字符串一称之为字符串二的字串。注意,并不要求子串(字符串一)的字符连续出现在字符串二中。
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印其中任意一个最长公共子串。
例如:BDCABA和ABCBDAB,字符串BCBA和BDAB都是它们的最长公共子串。
*/

#include<iostream>
#include<vector>
#include<assert.h>
#include<cstring>
using namespace std;

const int N = 100;
const int LEFT_UP = 1;
const int LEFT = 2;
const int UP = 3;

int f[N][N],path[N][N];

void initData(int len1, int len2)
{
    for(int i=0; i<len1; i++)
        for(int j=0; j<len2; j++)
        {
            f[i][j] = 0;
            path[i][j] = 0;
        }
}

//求str1和str2的LCS
int findLCS(char str1[], int len1, char str2[], int len2)
{
    initData(len1, len2);

    //第0行与第0列我们将其初始化为0,故从1开始计数。
    for(int i=1; i<=len1; i++)
        for(int j=1; j<=len2; j++)
        {
            if(str1[i] == str2[j])
            {
                f[i][j] = f[i-1][j-1] + 1;
                path[i][j] = LEFT_UP;
            }
            else if(f[i-1][j] >= f[i][j-1])
            {
                f[i][j] = f[i-1][j];
                path[i][j] = UP;
            }
            else
            {
                f[i][j] = f[i][j-1];
                path[i][j] = LEFT;
            }
            
        }
    return f[len1][len2];
}

//逆序打印LCS。
void printLCS(char str1[],int len1, char str2[], int len2)
{
    int i = len1;
    int j = len2;
    
    while(i>0 && j>0)
    {
        if(path[i][j] = LEFT_UP)
        {
            cout<<str1[i];
            i--;
            j--;
        }
        else if(path[i][j] = UP)
            i--;
        else
            j--;
    }

}


int main()
{
    char str1[] = "BDCABA";
    int len1 = 6;
    char str2[] = "ABCBDAB";
    int len2 = 7;

    cout<<"LCS length = "<<findLCS(str1,len1, str2,len2)<<endl;
    printLCS(str1,len1, str2,len2);
    cout<<endl;
    
    return 0;
}

 

 
posted @ 2012-07-11 10:07  Frank@609  Views(303)  Comments(0Edit  收藏  举报