由于您在 geeksforgeeks 中提到了链接Longest Palindromic Subsequence,因此我修改了解决方案以输出结果。我想我们需要一个辅助的二维数组来存储回文子序列是怎么来的,所以最后我们可以通过辅助数组得到结果。您可以在下面的代码中看到逻辑:
#include<iostream>
#include<cstring>
using namespace std;
// A utility function to get max of two integers
int max (int x, int y) { return (x > y)? x : y; }
// Returns the length of the longest palindromic subsequence in seq
int lps(char *str,char *result)
{
int n = strlen(str);
int i, j, cl;
int L[n][n]; // Create a table to store results of subproblems
int Way[n][n];// Store how the palindrome come from.
// Strings of length 1 are palindrome of lentgh 1
for (i = 0; i < n; i++)
{
L[i][i] = 1;
Way[i][i]=0;
}
// Build the table. Note that the lower diagonal values of table are
// useless and not filled in the process. The values are filled in a
// manner similar to Matrix Chain Multiplication DP solution (See
// http://www.geeksforgeeks.org/archives/15553). cl is length of
// substring
for (cl=2; cl<=n; cl++)
{
for (i=0; i<n-cl+1; i++)
{
j = i+cl-1;
if (str[i] == str[j] && cl == 2)
{
L[i][j] = 2;
Way[i][j]=0;
}
else if (str[i] == str[j])
{
L[i][j] = L[i+1][j-1] + 2;
Way[i][j]=0;
}
else
{
if(L[i][j-1]>L[i+1][j])
{
L[i][j]=L[i][j-1];
Way[i][j]=1;
}
else
{
L[i][j]=L[i+1][j];
Way[i][j]=2;
}
}
}
}
int index=0;
int s=0,e=n-1;
while(s<=e)
{
if(Way[s][e]==0)
{
result[index++]=str[s];
s+=1;
e-=1;
}
else if(Way[s][e]==1)e-=1;
else if(Way[s][e]==2)s+=1;
}
int endIndex=(L[0][n-1]%2)?index-1:index;
for(int k=0;k<endIndex;++k)result[L[0][n-1]-1-k]=result[k];
result[index+endIndex]='\0';
return L[0][n-1];
}
/* Driver program to test above functions */
int main()
{
char seq[] = "GEEKSFORGEEKS";
char result[20];
cout<<"The lnegth of the LPS is "<<lps(seq,result)<<":"<<endl;
cout<<result<<endl;
getchar();
return 0;
}
希望对你有帮助!
下面是解释:
令 X[0..n-1] 为长度为 n 的输入序列,L(0, n-1) 为 X[0..n-1] 的最长回文子序列的长度。
总共有5个案例。
1)每个字符都是长度为 1 的回文。
对于给定序列中的所有索引 i,L(i, i) = 1。
2) 只有 2 个字符,并且两个字符相同。
L(i, j) = 2。
3)有两个以上字符,首尾字符相同
L(i, j) = L(i + 1, j - 1) + 2
4)首尾字符不相同且L(i + 1, j)
5)首尾字符不相同且L(i + 1, j)>=L(i, j - 1)。 L(i, j) = L(i + 1, j)。
我们可以观察到,只有在情况 1,2 和 3 中,字符 X[i] 才会包含在最终结果中。我们用一个二维辅助数组来表示回文子序列是怎么来的。
案例 1、2、3 的值为 0;案例 4 的值为 1;案例 5 的值为 2。
用辅助数组方式。我们可以得到如下结果:
Let two variables s=0 and e=n-1.
While s<=e
Loop
If Way[s][e]==0 Then X[s] should be included in the result and we store it in our result array.
Else if Way[s][e]==1 Then X[s] should not be include in the result and update e=e-1 (because our result comes from case 4).
Else if Way[s][e]==2 Then X[s] should not be include in the result and update s=s+1 (because our result comes from case 5).
当 s>e 时应该终止循环。这样我们可以得到一半的结果,我们可以很容易地扩展它来得到整个结果。