字符串中最长的回文子串问题
2015-04-21 16:33
316 查看
此题参考
Manache算法,网上很多网友都说需要在转换后的字符串(即是在字符串中添加了‘#’)的最前面加上一个额外的字符,但是我觉得没有必要这么做: 最初的时候我选择第二个字符作为mid 然后寻找后面是否有更适合做mid的字符,如果有则替换。
具体代码实现如下:
#include <stdio.h>
#include <string.h>
#define MIN(a,b) ((a)>(b)?(b):(a))
void FullStr(char*res,char*des);
int FindMaxLen(char*res,int Len);
int main()
{
char Res[1000],Des[1000];
while (scanf("%s",Res)!=EOF)
{
FullStr(Res,Des);
printf("%d\n",FindMaxLen(Des,strlen(Des)));
}
return 0;
}
//讲原字符串中添加上‘#’使得奇数和偶数个字符可以按照相同的方式处理。
void FullStr(char*res,char*des)
{
int j=0;
for (int i=0;res[i]!='\0';i++)
{
des[j++]='#';
des[j++]=res[i];
}
des[j++]='#';
des[j]='\0';
}
//寻找最大的回文子串的长度
int FindMaxLen(char*res,int Len)
{
int P[2000]={0};
int max=2; //max代表最右边的最长子串的下标
int id=1; //最初的时候选择第二个字符作为最长子串的中间字符
P[0]=1;
P[1]=2;
for (int i=2;i<Len;i++)
{
if (max>i)
{
P[i]=MIN(max-i,P[2*id-i]); // 如果i在已有的最长子串的范围内,则比较i的对称点和i距离最长子串最右边的距离,选择较小者
}
else
{
P[i]=1;
}
while (i+P[i]<Len && i-P[i]>=0 && res[i+P[i]]==res[i-P[i]]) // i为中心向两边扩展
{
P[i]++;
}
if (P[i]>max-id+1) //如果作为中心的子串长度大于id为中心的子串长度,则替换id和max
{
id=i;
max=id+P[i]-1;
}
}
return max-id; //返回最长子串长度
}
Manache算法,网上很多网友都说需要在转换后的字符串(即是在字符串中添加了‘#’)的最前面加上一个额外的字符,但是我觉得没有必要这么做: 最初的时候我选择第二个字符作为mid 然后寻找后面是否有更适合做mid的字符,如果有则替换。
具体代码实现如下:
#include <stdio.h>
#include <string.h>
#define MIN(a,b) ((a)>(b)?(b):(a))
void FullStr(char*res,char*des);
int FindMaxLen(char*res,int Len);
int main()
{
char Res[1000],Des[1000];
while (scanf("%s",Res)!=EOF)
{
FullStr(Res,Des);
printf("%d\n",FindMaxLen(Des,strlen(Des)));
}
return 0;
}
//讲原字符串中添加上‘#’使得奇数和偶数个字符可以按照相同的方式处理。
void FullStr(char*res,char*des)
{
int j=0;
for (int i=0;res[i]!='\0';i++)
{
des[j++]='#';
des[j++]=res[i];
}
des[j++]='#';
des[j]='\0';
}
//寻找最大的回文子串的长度
int FindMaxLen(char*res,int Len)
{
int P[2000]={0};
int max=2; //max代表最右边的最长子串的下标
int id=1; //最初的时候选择第二个字符作为最长子串的中间字符
P[0]=1;
P[1]=2;
for (int i=2;i<Len;i++)
{
if (max>i)
{
P[i]=MIN(max-i,P[2*id-i]); // 如果i在已有的最长子串的范围内,则比较i的对称点和i距离最长子串最右边的距离,选择较小者
}
else
{
P[i]=1;
}
while (i+P[i]<Len && i-P[i]>=0 && res[i+P[i]]==res[i-P[i]]) // i为中心向两边扩展
{
P[i]++;
}
if (P[i]>max-id+1) //如果作为中心的子串长度大于id为中心的子串长度,则替换id和max
{
id=i;
max=id+P[i]-1;
}
}
return max-id; //返回最长子串长度
}
相关文章推荐
- 最长回文子串算法(字符串处理问题+多种方法解决)【转载】
- 最长回文子串(Manacher算法模板题)&&对称字符串问题
- 最长字符串回文子串问题
- 最长对称字符串问题/最长回文子串问题
- 最长公共子串、最长公共子序列、最长回文子串、模式匹配、最大子序列--字符串问题整理
- 最长公共子串、最长公共子序列、最长回文子串、模式匹配、最大子序列--字符串问题整理
- 字符串的最长回文子串问题
- Manarcher 求 字符串 的最长回文子串 【记录】
- 经典问题:最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)
- 给定一个字符串,求它的最长回文子串的长度,并打印出最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 算法的经典问题,求最长回文子串,最长重复字串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串 [转载]
- 重复子串问题(五):求最长回文字符子串
- 最长公共子串(子序列)、最长递增子序列、最长回文子串等问题
- 串子串Manacher算法: O(n)时间求字符串的最长回文子串
- C语言 求一个字符串中最长回文子串的长度