最长公共子序列的C++实现---附二维指针的使用方法
想了挺久到底第一篇在这儿的博客写什么好,刚好这两天又一次看到动态规划的LCS算法觉得还是有点意思的,就拿来写了写,第一篇博客就发它吧。
#include<iostream> #include<iomanip> using namespace std; //tag标志,0为左斜上,1取左,2取上;count为最长公共子序列计数 //计算最长公共子序列长度 void LCS_Length(char *X, char *Y, int *count[],int *tag[],int length_X, int length_Y) { //第一排第一列全部是0 for (int i = 0; i < length_X+1; i++) { count[i][0] = 0; } for (int i = 0; i < length_Y+1; i++) { count[0][i] = 0; } for (int i = 1; i <= length_X; i++) { for (int j = 1; j <= length_Y; j++) { if (X[i-1] == Y[j - 1]) { count[i][j] = count[i-1][j-1]+1; tag[i][j] = 0; } //否则取较大的值 else if(count[i-1][j] > count[i][j-1]) { count[i][j] = count[i-1][j]; tag[i][j] = 1; } else { count[i][j] = count[i][j-1]; tag[i][j] = 2; } } } } //打印最长公共子序列元素 void Print_LCS(int *tag[],char *X,int Length_X, int Length_Y) { if (Length_X == 0 || Length_Y == 0) { return ; } int i = Length_X, j = Length_Y; if (tag[i][j] == 0) { cout<<X[i-1]<<setw(4); Print_LCS(tag,X,i-1,j-1); } else if(tag[i][j] == 1) { Print_LCS(tag,X,i-1,j); } else { Print_LCS(tag,X,i,j-1); } } int main() { //先人为设置两个序列 char *X = "BDCABA"; char *Y = "ABCBDA"; int *count[7]; for (int i = 0; i < 7; i++) { count[i] = new int[7]; //因为第一行第一列全为0,所以总共七行七列 } int *tag[7]; for (int i = 0; i < 7; i++) { tag[i] = new int[7]; } LCS_Length(X,Y,count,tag,strlen(X),strlen(Y)); cout<<"最大子序列数为"<<count[6][6]<<endl; /**************************************** for(int i= 0; i <7; i++) { for (int j = 0; j < 7; j++) { cout<<count[i][j]<<setw(3); } cout<<endl; } *****************************************/ Print_LCS(tag,X,strlen(X),strlen(Y)); cout<<endl; return 0; }
主要函数有两个,一个函数是做出保存最长公共子序列的元素个数的矩阵,这里给出的示例中,两个字符串都各6个字符,所以给出的是7行7列矩阵(第一行第一列全为零)。
另外一个函数即为打印函数,从矩阵右下角一位开始遍历到[0][0]位,凡是遇到tag[i][j]标志为0则将该位的字符打印出来。算法比较简单易懂,具体可以参考《算法导论》。
下面补充说一个问题:二维指针到底怎么用。比如前面的二维数组初始化,如果我希望能够通过字符串的长度来给我的二维数组定义大小,而不是用常数来指定,使得我们可以通过strlen()函数来定义长度,那么就要用到二维指针。
注意:int *Arr[strlen(str)];这种声明方式是不正确的,编译器会提示错误,数组的声明必须使用常量。下面给出正确的示例:
/*********************************************** //华丽丽的分割线-------------------------------- 二维指针到底怎么用 int *(*ptr) = new int*[strlen(X)]; for (int i = 0; i < strlen(X); i++) { ptr[i] = new int[strlen(X)]; } ptr[2][3] = 0; cout<<ptr[2][3]<<endl; **********************************************/
/***Hello World***/