最長公共子序列LCS算法

思路:
對所有子問題s1[1-i]和s2[1-j]進行求解。s1[1-i]表示1~i範圍的s1子串,s2[1-j]表示1-j範圍的s2子串。

舉例:

#define N1 8
#define N2 9
int s1[N1+1] = {0,1,3,4,5,6,7,7,8 };
int s2[N2+1] = {0,3,5,7,4,8,6,7,8,2 };

其所有子問題如下:
s1[1~1],s2[1-1],求其最長公共子序列長度
s1[1~1],s2[1-2],求其最長公共子序列長度
s1[1~1],s2[1-2],求其最長公共子序列長度
s1[1~1],s2[1-3],求其最長公共子序列長度
s1[1~1],s2[1-4],求其最長公共子序列長度
s1[1~1],s2[1-5],求其最長公共子序列長度
s1[1~1],s2[1-6],求其最長公共子序列長度
s1[1~1],s2[1-7],求其最長公共子序列長度
s1[1~1],s2[1-8],求其最長公共子序列長度
s1[1~1],s2[1-9],求其最長公共子序列長度
s1[1~2],s2[1-1],求其最長公共子序列長度
s1[1~2],s2[1-2],求其最長公共子序列長度
s1[1~2],s2[1-3],求其最長公共子序列長度
s1[1~2],s2[1-4],求其最長公共子序列長度
s1[1~2],s2[1-5],求其最長公共子序列長度
s1[1~2],s2[1-6],求其最長公共子序列長度
s1[1~2],s2[1-7],求其最長公共子序列長度
s1[1~2],s2[1-8],求其最長公共子序列長度
s1[1~2],s2[1-9],求其最長公共子序列長度
s1[1~3],s2[1-1],求其最長公共子序列長度
s1[1~3],s2[1-2],求其最長公共子序列長度
s1[1~3],s2[1-3],求其最長公共子序列長度
s1[1~3],s2[1-4],求其最長公共子序列長度
s1[1~3],s2[1-5],求其最長公共子序列長度
s1[1~3],s2[1-6],求其最長公共子序列長度
s1[1~3],s2[1-7],求其最長公共子序列長度
s1[1~3],s2[1-8],求其最長公共子序列長度
s1[1~3],s2[1-9],求其最長公共子序列長度
s1[1~4],s2[1-1],求其最長公共子序列長度
s1[1~4],s2[1-2],求其最長公共子序列長度
s1[1~4],s2[1-3],求其最長公共子序列長度
s1[1~4],s2[1-4],求其最長公共子序列長度
s1[1~4],s2[1-5],求其最長公共子序列長度
s1[1~4],s2[1-6],求其最長公共子序列長度
s1[1~4],s2[1-7],求其最長公共子序列長度
s1[1~4],s2[1-8],求其最長公共子序列長度
s1[1~4],s2[1-9],求其最長公共子序列長度
s1[1~5],s2[1-1],求其最長公共子序列長度
s1[1~5],s2[1-2],求其最長公共子序列長度
s1[1~5],s2[1-3],求其最長公共子序列長度
s1[1~5],s2[1-4],求其最長公共子序列長度
s1[1~5],s2[1-5],求其最長公共子序列長度
s1[1~5],s2[1-6],求其最長公共子序列長度
s1[1~5],s2[1-7],求其最長公共子序列長度
s1[1~5],s2[1-8],求其最長公共子序列長度
s1[1~5],s2[1-9],求其最長公共子序列長度
s1[1~6],s2[1-1],求其最長公共子序列長度
s1[1~6],s2[1-2],求其最長公共子序列長度
s1[1~6],s2[1-3],求其最長公共子序列長度
s1[1~6],s2[1-4],求其最長公共子序列長度
s1[1~6],s2[1-5],求其最長公共子序列長度
s1[1~6],s2[1-6],求其最長公共子序列長度
s1[1~6],s2[1-7],求其最長公共子序列長度
s1[1~6],s2[1-8],求其最長公共子序列長度
s1[1~6],s2[1-9],求其最長公共子序列長度
s1[1~7],s2[1-1],求其最長公共子序列長度
s1[1~7],s2[1-2],求其最長公共子序列長度
s1[1~7],s2[1-3],求其最長公共子序列長度
s1[1~7],s2[1-4],求其最長公共子序列長度
s1[1~7],s2[1-5],求其最長公共子序列長度
s1[1~7],s2[1-6],求其最長公共子序列長度
s1[1~7],s2[1-7],求其最長公共子序列長度
s1[1~7],s2[1-8],求其最長公共子序列長度
s1[1~7],s2[1-9],求其最長公共子序列長度
s1[1~8],s2[1-1],求其最長公共子序列長度
s1[1~8],s2[1-2],求其最長公共子序列長度
s1[1~8],s2[1-3],求其最長公共子序列長度
s1[1~8],s2[1-4],求其最長公共子序列長度
s1[1~8],s2[1-5],求其最長公共子序列長度
s1[1~8],s2[1-6],求其最長公共子序列長度
s1[1~8],s2[1-7],求其最長公共子序列長度
s1[1~8],s2[1-8],求其最長公共子序列長度
s1[1~8],s2[1-9],求其最長公共子序列長度

所有子問題的答案都存在二維數組m中。
利用二維數組逆向輸出答案,具體過程直接看代碼就好。


代碼實現如下:

#include <iostream>
using namespace std;

int main()
{
#define N1 8
#define N2 9
    int s1[N1+1] = {0,1,3,4,5,6,7,7,8 };
    int s2[N2+1] = {0,3,5,7,4,8,6,7,8,2 };
    int m[9][10] = { 0 };

    for (int i = 1; i <= N1; i++) {
        for (int j = 1; j <= N2; j++) {
            if (s1[i] == s2[j]) {
                m[i][j] = m[i-1][j-1] + 1;
            }else{
                if (m[i - 1][j] > m[i][j - 1]) {
                    m[i][j] = m[i-1][j];
                }
                else {
                    m[i][j] = m[i][j-1];
                }
            }
        }
    }

    // 輸出數組m
    for (int i = 0; i <= N1; i++) {
        for (int j = 0; j <= N2; j++) {
            cout << m[i][j] << " ";
        }
        putchar(10);
    }

    // 輸出答案
    cout << "倒序輸出答案:";
    int i = N1, j = N2;
    while (i >= 1 && j >= 1) {
        if (s1[i] == s2[j]) {
            cout << s1[i] << " ";
            i--; j--;
        }
        else {
            if (m[i - 1][j] > m[i][j - 1]) {
                i--;
            }
            else {
                j--;
            }
        }
    }


    putchar(10);
    return 0;
}


參考:https://blog.csdn.net/UncleJokerly/article/details/79701073

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章