LCS-動態規劃算法詳解

LCS 思想講解:
在這裏插入圖片描述

#include<iostream>
#include<string.h>
using namespace std;
/**
 * @param {type} string X I am argument string X. 
 * @param {type} string Y I am argument string Y. 
 * @param {type} int **B 存儲方向變量-B[i][j]表示C[i][j]的值是由哪個子問題得到的. 
 *
 *                  0;                  當i = 0 或 j = 0時
 * C[i][j] =    c[i-1][j-1]+1;          當i>0,j>0且Xi=Yj時
 *           max(C[i-1][j], C[i][j - 1]);當i>0,j>0且Xi≠Yj時
 */

/*
int **Lcs_Length(string X, string Y, int **B){
    int x_len = X.length();
    int y_len = Y.length();

    int **C = new int *[x_len + 1];//用於存放最優解
    for (int i = 0; i < x_len; i++)
    {
        C[i] = new int[y_len];
    }
    
    for (int i = 1; i < x_len; i++){
        C[i][0] = 0;
        B[i][0] = -2;//-2表示沒有方向
    }

    for (int i = 0; i <= y_len; i++)
    {
        C[0][i] = 0;
        B[0][i] = -2;
    }

    for (int i = 1; i <= x_len; i++)
    {
        for(int j = 1; j <= y_len; j++){
            if(X[i - 1] == Y[j - 1]){
                C[i][j] = C[i - 1][j - 1] + 1;
                B[i][j] = 0;//0表示斜向左上
            }
            else{
                if(C[i - 1][j] >= C[i][j - 1]){
                    C[i][j] = C[i - 1][j];
                    B[i][j] = -1;
                }
                else{
                    C[i][j] = C[i][j - 1];
                    B[i][j] = 1;//1表示橫向左
                }
            }
        }
    }
    
    return C;
}

void OutPutLCS(int** B, string X, int str1_len, int str2_len){
    if(str1_len == 0 || str2_len == 0){
        return;
    }
    if(B[str1_len][str2_len] == 0){
        OutPutLCS(B, X, str1_len - 1, str2_len);
        printf("%c", X[str1_len - 1]);
    }
    else if(B[str1_len][str2_len] == -1){
        OutPutLCS(B, X, str1_len - 1, str2_len);
    }
    else{
        OutPutLCS(B, X, str1_len, str2_len - 1);
    }
}

int main(int argc, char const *argv[])
{
    string X = "ABCBDAB";
    string Y = "BDCABA";
    int x_len = X.length();
    int y_len = Y.length();

    int **C;
    int **B = new int *[x_len + 1];
    for (int i = 0; i <= x_len; i++)
    {
        B[i] = new int[y_len + 1];
    }

    C = Lcs_Length(X, Y, B);

    for (int i = 0; i < x_len; i++)
    {
        for (int j = 0; j <= y_len; j++)
        {
            cout << C[i][j] << " ";
        }
        cout << endl;
        
    }

    for (int i = 0; i <= x_len; i++)
    {
        for (int j = 0; j <= y_len; j++)
        {
            cout << B[i][j] << " ";
        }
        cout<<endl;
        
    }
    
    OutPutLCS(B, X, x_len, y_len);
    system("pause");
    
    return 0;
}
*/


 
int **Lcs_length(string X,string Y,int **B)
{
	int x_len = X.length();
	int y_len = Y.length();
 
	int **C = new int *[x_len+1];
	for (int i = 0; i <= x_len; i++)
	{
		C[i] = new int[y_len + 1];        //定義一個存放最優解的值的表;
	}
 
	for (int i = 1; i <= x_len; i++)
	{
		C[i][0] = 0;
		B[i][0] = -2;                     //-2表示沒有方向
	}
 
 
	for (int j = 0; j <= y_len; j++)
	{
		C[0][j] = 0;
		B[0][j] = -2;
	}
	
	for (int i = 1; i <= x_len; i++)
	{
		for (int j = 1; j <= y_len; j++)
		{
 
			if (X[i-1]==Y[j-1])
			{
				C[i][j] = C[i - 1][j - 1] + 1;
 
				B[i][j] = 0;             //0表示斜向左上
			}
			else
			{
				if (C[i-1][j]>=C[i][j-1])
				{
					C[i][j] = C[i - 1][j];
					B[i][j] = -1;       //-1表示豎直向上;
				}
				else
				{
					C[i][j] = C[i][j - 1];
					B[i][j] = 1;        //1表示橫向左
				}
			}
 
		}
	}
	return C;
}

 
void OutPutLCS(int **B, string X,int str1_len,int str2_len)
{
	
	if (str1_len == 0 || str2_len == 0)
	{
		return;
	}
	if (B[str1_len][str2_len] == 0)   //箭頭左斜
	{
		OutPutLCS(B, X, str1_len - 1, str2_len - 1);
		printf("%c", X[str1_len - 1]);
	}
	else if (B[str1_len][str2_len] == -1)
	{
		OutPutLCS(B, X, str1_len - 1, str2_len);
	}
	else
	{
		OutPutLCS(B, X, str1_len, str2_len-1);
	}
}
 
int main()
{
	string X = "ABCBDAB";
	string Y = "BDCABA";
 
	int x_len = X.length();
	int y_len = Y.length();
 
	int **C;
 
	int **B = new int *[x_len + 1];
	for (int i = 0; i <= x_len; i++)
	{
		B[i] = new int[y_len + 1];
	}
 
 
	C = Lcs_length(X, Y, B);
 
	for (int i = 0; i <= x_len; i++)
	{
		for (int j = 0; j <= y_len; j++)
		{
			cout << C[i][j]<<" ";
		}
		cout << endl;
	}
 
	cout << endl;
 
	for (int i = 0; i <= x_len; i++)
	{
		for (int j = 0; j <= y_len; j++)
		{
			cout << B[i][j] << " ";
		}
		cout << endl;
	}
 
	OutPutLCS(B, X, x_len, y_len);
 
	system("pause");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章