题目:
输入字符串中对称的子字符串的最大长度。比如输入字符串“roorle”,由于该字符串里最长的对称子字符串是“roor”,因此输出4.
思路:
1、求字符串”roorle“和反序”elroor“的最长公共子串
2、最长回文子串
代码:
1、最长公共子串
#include<iostream> using namespace std; // naive method // O(n^3) int comlen(const string &str1,int i,int m,const string &str2,int j,int n){ int len=0; while(i<m && j<n && str1[i++]==str2[j++]) len++; return len; } int LongestCommonSubString(const string &str1,const string &str2){ int m=str1.size(); int n=str2.size(); int maxLen=0; int maxIndex=-1; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ int len=comlen(str1,i,m,str2,j,n); if(len>maxLen){ maxLen=len; maxIndex=i; } } } for(int i=0;i<maxLen;i++){ cout<< str1[maxIndex+i] <<" "; } cout<<endl; return maxLen; } // DP method // O(n^2) int LongestCommonSubString_1(const string &str1,const string &str2){ int m=str1.size(); int n=str2.size(); int dp[m][n]; for(int i=0;i<m;i++){ for(int j=0;j<n;j++) dp[i][j]=0; } int maxLen=0; int maxIndex; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(str1[i]==str2[j]){ if(i>0 && j>0) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=1; } if(dp[i][j]>maxLen){ maxLen=dp[i][j]; maxIndex=i-maxLen+1; } } } for(int i=0;i<maxLen;i++) cout<<str1[maxIndex+i]<<" "; cout<<endl; return maxLen; } // DP method // O(n^2) int LongestCommonSubString_2(const string &str1,const string &str2){ int m=str1.size(); int n=str2.size(); int dp[m][n]; for(int i=0;i<m;i++){ for(int j=0;j<n;j++) dp[i][j]=0; } int maxLen=0; int maxIndex; for(int i=m-1;i>=0;i--){ for(int j=n-1;j>=0;j--){ if(str1[i]==str2[j]){ if(i<m-1 && j<n-1) dp[i][j]=dp[i+1][j+1]+1; else dp[i][j]=1; } if(dp[i][j]>maxLen){ maxLen=dp[i][j]; maxIndex=i; } } } for(int i=0;i<maxLen;i++) cout<<str1[maxIndex+i]<<" "; cout<<endl; return maxLen; } // DP method // O(n^2) int LongestCommonSubString_3(const string &str1,const string &str2){ int m=str1.size(); int n=str2.size(); int dp[m+1][n+1]; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++) dp[i][j]=0; } int maxLen=0; int maxIndex; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(str1[i]==str1[j]) dp[i][j]=dp[i-1][j-1]+1; if(dp[i][j]>maxLen){ maxLen=dp[i][j]; maxIndex=i-maxLen+1; } } } for(int i=0;i<maxLen;i++) cout<<str1[maxIndex+i]<<" "; cout<<endl; return maxLen; } int main(){ string str1="abcdefg"; string str2="bgfcdft"; cout<<LongestCommonSubString(str1,str2)<<endl; cout<<LongestCommonSubString_1(str1,str2)<<endl; cout<<LongestCommonSubString_2(str1,str2)<<endl; cout<<LongestCommonSubString_3(str1,str2)<<endl; return 0; }
2、最长回文子串
#include<iostream> using namespace std; // brute force string findLongestPalindrome_1(const string &str){ int length=str.size(); int maxLength=0; int start; for(int i=0;i<length;i++){ for(int j=i+1;j<length;j++){ int left,right; for(left=i,right=j;left<right;left++,right--){ if(str[left]!=str[right]) break; } if(left>=right && (j-i)>maxLength){ maxLength=j-i+1; start=i; } } } if(maxLength>0) return str.substr(start,maxLength); return NULL; } // dynamic programming string findLongestPalindrome_2(string &str){ const int length=str.size(); int maxLength=1; int start; bool dp[length][length]; for(int i=0;i<length;i++) for(int j=0;j<length;j++) dp[i][j]=false; for(int i=0;i<length;i++){ dp[i][i]=true; if(i<length-1 && str[i]==str[i+1]){ dp[i][i+1]=true; start=i; maxLength=2; } } for(int len=3;len<=length;len++){ for(int i=0;i<=length-len;i++){ int j=i+len-1; if(dp[i+1][j-1] && str[i]==str[j]){ dp[i][j]=true; start=i; maxLength=len; } } } if(maxLength>=2) return str.substr(start,maxLength); return NULL; } // pivot expand string findLongestPalindrome_3(string &str){ const int length=str.size(); int maxLength=1; int start; // length is odd for(int i=0;i<length;i++){ int left=i-1; int right=i+1; while(left>=0 && right<=length-1 && str[left]==str[right]){ if(right-left+1>maxLength){ start=left; maxLength=right-left+1; } left--; right++; } } // length is even for(int i=0;i<length;i++){ int left=i; int right=i+1; while(left>=0 && right<=length-1 && str[left]==str[right]){ if(right-left+1>maxLength){ start=left; maxLength=right-left+1; } left--; right++; } } if(maxLength>0) return str.substr(start,maxLength); return NULL; } int main(){ string str="ababcddcbbd"; cout<<findLongestPalindrome_1(str)<<endl; cout<<findLongestPalindrome_2(str)<<endl; cout<<findLongestPalindrome_3(str)<<endl; return 0; }