Longest Palindrome
回文基础:
如果子串P是回文,那么xPx是回文。
如果子串P不是回文,那么xPx不是回文。
根据回文基础,我们可以得到 动态规划的状态转移函数。
设置 状态量LP[i][j]来表示任意某个子串a[i]...a[j]是否是回文。
那么,
1. 初始条件:
代码:
回文基础:
如果子串P是回文,那么xPx是回文。
如果子串P不是回文,那么xPx不是回文。
根据回文基础,我们可以得到 动态规划的状态转移函数。
设置 状态量LP[i][j]来表示任意某个子串a[i]...a[j]是否是回文。
那么,
1. 初始条件:
空串 看作是回文的最初始条件,LP[i][i-1]=1。这作为初始状态,并不认为是有回文。
单字符串 是直接认为有回文的,LP[i][i]=1。
2. 状态转移:若LP[i][j]=1且a[i-1]==a[j+1] ,那么有LP[i-1][j+1]=1,否则LP[i-1][j+1]=0
将这一思路写出代码:
//检测所有长度的子串
for(m=1;m<=len;m++) //m代表当前子串长度,相当于gap
for(i=1;i<len-m+1;i++) //i是当前子串起始
{
j = i+m-1; //j是当前子串末尾
//设置left和right保存当前最长回文,其起初可设置为不可能的情况。
//注意这里单字符串要认为是有回文。
if((i==j)||(LP[i+1][j-1]==1 && a[i]==a[j]))
{
LP[i][j] = 1;
if(m > right-left+1)
{
left = i;
right = j;
}
}
else
LP[i][j] = 0;
}
代码:
特别要注意边界问题。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define N 100
char* LongestPalindrome(char* a)
{
int left=2, right=0;
int i,j,m;
int LP[N][N];
int len = strlen(a);
if(a==NULL || len==0)
return NULL;
if(len==1)
return a;
//初始化状态
for(i=1;i<len;i++)
LP[i][i-1] = 1; //将这种临界的不可能状态设为1
//检测所有长度的子串
for(m=1;m<=len;m++) //m代表当前子串长度
for(i=0;i<len-m+1;i++) //i是当前子串起始
{
j = i+m-1; //j是当前子串末尾
if((i==j)||(LP[i+1][j-1]==1 && a[i]==a[j]))//注意这里单字符串要认为是回文
{
LP[i][j] = 1;
if(m > right-left+1)
{
left = i;
right = j;
}
}
else
{
LP[i][j] = 0;
}
}
//printf("%d %d\n", left, right);
if(left == right)
{
char *result = (char*)malloc(sizeof(char)*(right-left+1+1));
result[0] = a[left];
return result;
}
else
{
char *result = (char*)malloc(sizeof(char)*(right-left+1+1));
for(i=0;i<right-left+1;i++)
result[i] = a[left+i];
result[right-left+1] = '\0';
return result;
}
}
int main()
{
char a[N];
int len;
char *b;
while(scanf("%s",a)!=EOF)
{
b = LongestPalindrome(a);
len = strlen(b);
printf("%d\n", len);
printf("%s\n",b);
}
return 1;
}