您的位置:首页 > 其它

求一个字符串中最长回文子串的长度(承接上一个题目)

2011-12-21 12:08 369 查看
问题描述:如题,给定一个字符串str和其长度n,求该字符串的一个最长公共回文子串的长度(公共子串个公共子序列是两个不同的概念)。并打印出该回文子串。
解答:1,首先给出一个比较直观的解法。根据回文的性质,我们可以把str进行逆转得到str1,然后求str和str1的最长公共子串,那么该子串的长度就是str的最长回文子串的长度,该公共子串就是最长的那个回文子串。也即我们把这个题目转化为求两个字符串str和str1的最长公共子串的问题。我们假设C[i,j]为以str[i]和str1[j]结尾的最长公共子串的长度,那么状态转移方程为:
C[i,j]=0 if(str[i]!=str1[j])C[i,j]=c[i-1,j-1]+1 if(str[i]==str1[j])
初始条件为C[0,0]=0;最初的时间代价为O(n^2),空间代价为O(n^2),空间代价还可以优化为O(n),只需要j的循环式从高往低即可。代码如下://求str1和str2的最长公共子串,下标从1算起void LCS_continue(char *str1,int n1,char *str2,int n2){ int **C=new int*[n1+1]; for(int i=0;i<=n1;i++){ C[i]=new int[n2+1](); } int max=0; int max_index_i=0; int max_index_j=0; for(int i=1;i<=n1;i++){ for(int j=1;j<=n2;j++){ if(str1[i]==str2[j]) C[i][j]=C[i-1][j-1]+1; else C[i][j]=0; if(C[i][j]>max){ max=C[i][j]; max_index_i=i; max_index_j=j; } } } cout<<"最长公共子串长度为:"<<max<<ends; if(max>0){ cout<<"子串为:"<<ends; while(str1[max_index_i]==str2[max_index_j--]){ cout<<str1[max_index_i--]<<ends; } } //free mem for(int i=0;i<=n1;i++){ delete [] C[i]; } delete [] C;}空间优化:void LCS_continue_OPM(char *str1,int n1,char *str2,int n2){ int *C=new int[n2+1](); int max=0; int max_index_j=0; for(int i=1;i<=n1;i++){ for(int j=n2;j>0;j--){ if(str1[i]==str2[j]) C[j]=C[j-1]+1; else C[j]=0; if(C[j]>max){ max=C[j]; max_index_j=j; } } } cout<<"最长公共子串长度为:"<<max<<ends; if(max>0){ cout<<"子串为:"<<ends; while(max>0){ cout<<str2[max_index_j--]<<ends; max--; } } //free mem delete [] C;}2,下面给出一个直观的动规解,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐