1. 程式人生 > >最長公共子序列--【算法導論】

最長公共子序列--【算法導論】

pan end art blog src http size ret bdc

最長公共子序列:一個序列 S 。假設各自是兩個或多個已知序列的子序列,且是全部符合此條件序列中最長的,則 S 稱為已知序列的最長公共子序列。

其核心非常easy:

技術分享

這樣,構造子結構就比較簡單了:

if(str1[i - 1] == str2[j - 1])
m[i][j] = m[i - 1][j - 1] + 1;
else
m[i][j] = max(m[i - 1][j], m[i][j - 1]);

前面動態規劃思想說得足夠了,這次直接貼:

#include <iostream>
#include <cstring>

using namespace std;

void Print(int **m, int lena, int lenb, char *str1)
{
    //int length = m[lena][lenb];
    if(0 == lena || 0 == lenb)
        return ;
    else if(m[lena][lenb] == m[lena - 1][lenb - 1] + 1)
    {
        Print(m, lena - 1, lenb - 1, str1);
        cout << str1[lena - 1];
    }
    else if(m[lena - 1][lenb] > m[lena][lenb - 1])
        Print(m, lena, lenb - 1, str1);
    else
        Print(m, lena - 1, lenb, str1);
}

int Lcs(char *str1, char *str2)
{
    int lena = strlen(str1);
    int lenb = strlen(str2);

    int **m = new int*[lena + 1];
    for(int i = 0; i < lena + 1; i++)
        m[i] = new int[lenb + 1];

    for(int i = 0; i < lena + 1; i++)
    {
        for(int j = 0; j < lenb + 1; j++)
            m[i][j] = 0;
    }
    for(int i = 1; i < lena + 1; i++)
    {
        for(int j = 1; j < lenb + 1; j++)
        {
            if(str1[i - 1] == str2[j - 1])
                m[i][j] = m[i - 1][j - 1] + 1;
            else
                m[i][j] = max(m[i - 1][j], m[i][j - 1]);
        }
    }

    for(int i = 0; i < lena + 1; i++)
    {
        for(int j = 0; j < lenb + 1; j++)
            cout << m[i][j] << " ";
        cout << endl;
    }
    Print(m, lena, lenb, str1);
    return m[lena][lenb];
}

int main()
{
    char str1[] = "ACBDCDB";
    char str2[] = "ADCBEB";

    cout << endl << Lcs(str1, str2) << endl;
    return 0;
}
技術分享

上述輸出分別為匹配的二維數組結果,最長公共子序列(當中之中的一個),長度;


O(∩_∩)O(不足之處請不吝賜教)

最長公共子序列--【算法導論】