动态规划基础——最长公共子序列

问题:求两字符串的最长公共子序列。

当然,要注意的是并没要求连续,连续的话就是子串了。

如:s1 = "abc"; s2 = "adc";

substring = "ac";

解这题的思想,就是运用已知结果来计算未知。

在对字符是否相等进行判断时,需要记下当前公共子序列长度,为以后判断使用:

如开始判断s1[i] 与 s2[j]是否相等:

当两个字符相等时,显然,当前子序列长度 c[i][j] = c[i-1][j-1] +1 

 

当两个字符不相等时,s1[i]与s2[j]的公共子序列就是 s1[i-1]与s2[j]、s1[i]与s2[j-1]这两对字符串当中公共子序列最长的那一个,并且 c[i][j] 设为此长度。

 

 c[i][j] = c[i-1][j-1] +1 (s1[i]==s2[j])

 

   c[i][j] = c[i-1][j] (s1[i]!=s2[j]&&c[i-1][j]>c[i][j-1])

 

   c[i][j] = c[i][j-1] (s1[i]!=s2[j]&&c[i-1][j]<c[i][j-1])

 

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string>
//本函数未返回最长公共子序列,只是求出各个子串的公共子序列
void MaxLength( char* s1, char* s2)
{
    int l1 = strlen(s1);
    int l2 = strlen(s2);
    //子串
    char ***substring;
    int **c;
    //构造数组c[l1][l2],存储各状态下,公共子串长度
//在本函数中*substring[i][j]与c[i][j]均表示s1长度为i的子串与s2长度为j的子串的公共子序列及其长度
c = new int*[l1+1]; for(int i = 0; i <= l1; i++) { c[i] = new int[l2+1]; for(int j =0; j <= l2; j++) c[i][j] = 0; } //为子串分配空间(最长为相应s2子串长度) substring = new char**[l1+1]; for(int i = 0; i <= l1 ; i++) substring[i] = new char*[l2+1]; for(int i = 0; i <= l1; i++) for(int j = 0; j <= l2; j++) { substring[i][j] = new char[j+1]; //if( i == 0 || j == 0) *substring[i][j] = NULL; } for(int i = 0; i < l1; i++) { for(int j = 0; j < l2; j++) { if(s1[i] == s2[j]) { c[i+1][j+1] = c[i][j] + 1; //先将先前结果赋给substring[i+1][j+1] strncat(substring[i+1][j+1],substring[i][j],strlen(substring[i][j])); //增添新字符 strncat(substring[i+1][j+1] ,s1 + i,1); } else if(c[i+1][j]<c[i][j+1]) { c[i+1][j+1] = c[i][j+1]; strcpy(substring[i+1][j+1],substring[i][j+1]); } else { c[i+1][j+1] = c[i+1][j]; strcpy(substring[i+1][j+1], substring[i+1][j]); } } } for(int i = 0; i < l1; i++) { for(int j = 0; j <l2; j++) { printf("s1[%d]与s2[%d]的长度是%d,内容是:%s\n",i+1,j+1,c[i+1][j+1],substring[i+1][j+1]); //delete 释放内存空间(末节点未被释放,可单独写释放函数) delete []substring[i][j]; } delete []substring[i]; delete []c[i]; } delete []substring; delete []c; }
//测试函数
int main() { char *s1="11abac"; char *s2="a11ac"; MaxLength(s1,s2); return 0; }

 

 

 

posted @ 2013-06-22 21:25  idealing  阅读(151)  评论(0)    收藏  举报