最长公共子序列(未完成)

来源:互联网 发布:编程常用语言有哪些 编辑:程序博客网 时间:2024/05/29 04:45

做了滚动数组的lcs,每次都只会用到本行和上一行的数据,因此只需记录了两行就能够算出结果。

使用滚动数组是不是无法追踪解的情况?

关于i-1这种问题的越界处理,有两种处理方法:一种是输入的数组前面加个无意义字符,让有意义的数据从1开始;另一种是 解空间从1开始计算,如本例中C[i][j]的的下标。

#include <iostream>using namespace std;char A[7]={'a','b','c','b','d','a','b'};char B[6]={'b','d','c','a','b','a'};int C[2][9]={0};char X[9] = {0};int main() {    for (int k = 0; k < 2; ++k) {        C[k][0] = 0;    }    for (int l = 0; l < 6; ++l) {        C[0][l] = 0;    }    for (int i = 1; i <= 7; ++i) {        for (int j = 1; j <= 6; ++j) {            if (A[i-1] == B[j-1]){                C[i%2][j] = C[(i-1)%2][j-1] + 1;//用i%2来让数字i在0,1之间滚动            }            else{                C[i%2][j] = max(C[i%2][j-1],C[(i-1)%2][j]);            }        }    }    cout << C[7%2][6] <<endl;    return 0;}

未做滚动数组的LCS,做了 解的跟踪

#include <iostream>using namespace std;char A[7]={'a','b','c','b','d','a','b'};char B[6]={'b','d','c','a','b','a'};int C[8][7]={0};char D[8][6] = {0};void lscTrace(int i,int j);int main() {    for (int k = 0; k < 8; ++k) {        C[k][0] = 0;    }    for (int l = 0; l < 7; ++l) {        C[0][l] = 0;    }    for (int i = 1; i <= 7; ++i) {        for (int j = 1; j <= 6; ++j) {            if (A[i-1] == B[j-1]){                C[i][j] = C[i-1][j-1] + 1;                D[i][j] = 1;            }            else{                C[i][j] = max(C[i][j-1],C[i-1][j]);                if (C[i][j-1] > C[i-1][j])                    D[i][j] = 2;                else                    D[i][j] = 3;            }        }    }    cout << C[7][6] <<endl;    lscTrace(7,6);    return 0;}void lscTrace(int i,int j){    if (i==0 || j==0){        return;    }    if (D[i][j] == 1){        lscTrace(i-1,j-1);//如果这句放在cout后面输出就是反的!        cout << A[i-1] <<" ";    } else if (D[i][j] == 2){        lscTrace(i,j-1);    } else if (D[i][j] == 3){        lscTrace(i-1,j);    }}

上面解只输出了一个,如果要求输出所有解得lcs?怎么办?下面的代码并没有实现输出所有解,有待重写,参考如下两篇文章。

http://blog.csdn.net/v_july_v/article/details/6695482

http://www.cnblogs.com/wb-DarkHorse/archive/2012/11/15/2772520.html

论文:《最长公共子序列问题的改进快速算法_李欣S》

#include <iostream>using namespace std;char A[7]={'a','b','c','b','d','a','b'};char B[6]={'b','d','c','a','b','a'};int C[8][7]={0};int D[8][7] = {0};void lscTrace(int i,int j);int main() {    for (int k = 0; k < 8; ++k) {        C[k][0] = 0;    }    for (int l = 0; l < 7; ++l) {        C[0][l] = 0;    }    for (int i = 1; i <= 7; ++i) {        for (int j = 1; j <= 6; ++j) {            if (A[i-1] == B[j-1]){                C[i][j] = C[i-1][j-1] + 1;                D[i][j] = 1;            }            else{                C[i][j] = max(C[i][j-1],C[i-1][j]);                if (C[i][j-1] > C[i-1][j])                    D[i][j] = 2;                else if(C[i][j-1] == C[i-1][j])                    D[i][j] = 4;                else if(C[i][j-1] < C[i-1][j])                    D[i][j] = 3;            }        }    }    cout << C[7][6] << endl;    lscTrace(7,6);    return 0;}int flag = 0;char ans[10] = {0};void lscTrace(int i,int j){    flag = 0;    if (i==0 || j==0){        cout << "  end" << endl;        flag = 1;        return;    }    else {        if (D[i][j] == 1) {            lscTrace(i - 1, j - 1);//如果这句放在cout后面输出就是反的!            if (flag)                cout << A[i - 1] << " ";        } else if (D[i][j] == 2) {            lscTrace(i, j - 1);        } else if (D[i][j] == 3) {            lscTrace(i - 1, j);        } else if (D[i][j] == 4) {            lscTrace(i - 1, j);            lscTrace(i, j - 1);        }    }}

思考1:上面求解解空间使用深度搜索怎么搜?广度怎么搜?

思考2:如何追踪解?只要知道每个解是如何得来的,然后就可以使用此办法得出解空间。本例中就是利用了1,2,3,4来表示解是由那个地方来的,然后实现追踪。

思考3:由两篇论文去思考矩阵中只有知道一定的限制条件如何求解特定问题?学习解题思路。S

0 0
原创粉丝点击