15-2(最长的回文序列) 回文(palindrome)它是一个正序和反向同一非空字符串。例如。全长1串,civic,racecar,aibohphobia他们是回文。设计一个有效的算法。文子序列。
比如,给定输入character,算法应该返回carac.算法的执行时间是怎么样的?
解题思路:首先我们要注意的是题目要求求出最长回文子序列,而不是子串。
假设是子串。比方abcdebca,该回文子串长度为1,是当中随意一个字符,而回文子序列是abcdbca(abcebca).所以求子串和子序列有一些不同。下面方法仅仅适用求子序列,求子串方法因为题目没有要求,这里暂且不提了。(PS:有些人可能不清楚子串和子序列的差别,这是要特别注意的问题。)
详细方法:仅仅要把原字符串逆转后和原字符串比較而且利用求最长公共子序列的方式求出的LCS就可以得到最长回文子序列。
也就是说 求出的LCS=最长回文子序列。
代码例如以下:
#include <iostream>
using namespace std;
#define N 9//输入您要推断的字符串字符数
char*strReversal(char*str)
{
for (int i=0;i<N/2;i++)
{
swap(str[i],str[N-i-1]);
}
return str;
}
char *b[N+2][N+2]={NULL};
int c[N+2][N+2]={0};
void Lcs_Length(char *x, char *y)
{
for (int i=0;i<N;i++)
{
for (int j=0;j<N;j++)
{
if (x[i]==y[j])
{
c[i+1][j+1]=c[i][j]+1;
b[i+1][j+1]="↖";
}
else
{
if (c[i][j+1]>=c[i+1][j])
{
c[i+1][j+1]=c[i][j+1];
b[i+1][j+1]="↑";
}
else
{
c[i+1][j+1]=c[i+1][j];
b[i+1][j+1]="←";
}
}
}
}
}
void PRINT_LCS(char*x,int i,int j)
{
if (i==0||j==0)
{
return;
}
if (b[i][j]=="↖")
{
PRINT_LCS(x,i-1,j-1);
cout<<x[i-1]<<" ";
}
else
{
if (b[i][j]=="↑")
{
PRINT_LCS(x,i-1,j);
}
else
{
PRINT_LCS(x,i,j-1);
}
}
}
void main()
{//为了和书中代码吻合,数组第一个位置存放空字符。
char x[N+1]={0};
char y[N+1]={0};
char c;
cout<<"提示:输入字符串之前。依据须要设置N大小"<<endl;
cout<<"请输入须要推断的字符串:"<<endl;
for (int i=0;i<N;i++)
{
cin>>c;
y[i]=x[i]=c;
}
y[i]='