LCS, LIS, 线性空间LCS( hirschberg算法)

 今天帮同学写了三个代码,分别是简单LCS,LIS,以及使用线性空间的LCS。

首先是LCS(longest common substring最长公共子序列),这是动态规划的典型例题,各种算法书里都会讲到的一个问题。个人推荐这个网页http://blog.163.com/hzzy-010/blog/static/79692381200872024242126/ 。 讲的非常清楚,图例也很好,可以把你从不懂讲到懂。由于他讲的实在很详细,我就不好意思再说了。直接上代码了。代码比较搓,将就着看吧。

#include #include #define MAXLEN 100 int max_three(int a,int b,int c,int &back) { int max = a; back = 0; if(max < b) { max = b; back = 1; } if(max < c) { max = c; back = 2; } return max; } int main() { char x[MAXLEN]; char y[MAXLEN]; int matrix[MAXLEN][MAXLEN]; int back[MAXLEN][MAXLEN]; char result[MAXLEN]; printf("input string a/n"); scanf("%s",&x); printf("input string b/n"); scanf("%s",&y); int xlen = strlen(x); int ylen = strlen(y); for(int i=0;i=0;i--) printf("%c",ans[i]); printf("/n"); }

LIS(longest increasing substring)也是一个动态规划问题,有O(n2)以及O(nlogn)两种解法,我用了比较简单的算法。具体的递推公式是:len(i) = max{str[i] > str[j]? len[i]+1 : 1} 0=< j < i; 然后我们从len的数组中找到最长子串,注意不是说最后一个len一定是最长的。然后输出。代码如下:

#include #include #define MAXLEN 100 int main() { char x[MAXLEN]; int l[MAXLEN]; int pro[MAXLEN]; for(i=0;i x[j]?l[j]+1:1; if(max =0;i--) { if(lis =0;i--) { printf("%c",ans[i]); } printf("/n"); }

线性空间LCS,这是使用线性的空间来解LCS问题,主要为了解决长字符串而由hirschberg发明的。可以看维基上的介绍:http://en.wikipedia.org/wiki/Hirschberg%27s_algorithm,当然也可以找他的论文看看,名字叫:A Linear Space Algorithm for Computing Maximal Common Subsequences 。这个解法使用到了动态规划以及分治算法,在时间复杂度上面有所增加,但是减少了空间复杂度。它首先把a数组一分为二,然后考虑所有的b数组二分的方法,找到一个subsequence最长的方法,然后将两个数组一分为二,分别再次计算。这个算法之所以可以成功,还有一个原因就是下面代码中的LCS_B算法可以使用线性空间获得最长子序列的长度。好了,代码如下:

 #include #include #define MAXLEN 100 void reverstring(char* x,char* xr) { int len = strlen(x); for(int i=0;ib?a:b; } void LCS_B(int m, int n, char* A, char* B, int& L) { int K[2][MAXLEN]; for(int j=0;j<=n;j++) K[1][j] = 0; for(int i=1;i<=m;i++) { for(int j=0;j<=n;j++) K[0][j] = K[1][j]; for(int j=1;j<=n;j++) { if(A[i-1] == B[j-1]) { K[1][j] = K[0][j-1]+1; } else K[1][j] = max(K[1][j-1],K[0][j]); } } L = K[1][n]; } void LCS_A(int m,int n,char* x, char* y, char* res) { char xr[MAXLEN]; char yr[MAXLEN]; x[m] = '/0'; y[n] = '/0'; reverstring(x, xr); reverstring(y, yr); if(n==0) { strcpy(res,""); return; } if(m==1) { for(int i=0;i

你可能感兴趣的:(LCS, LIS, 线性空间LCS( hirschberg算法))