import java.util.Scanner;
public class Manacher {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
String inStr = in.nextLine();
manacher(inStr);
}
public static int manacher (String str){
char [] cStr = str.toCharArray();
StringBuffer sBuffer = new StringBuffer();
//增加#,相当于length*2+1.都变成了奇数长度。
sBuffer.append("#");
for (int i = 0; i < cStr.length; i++) {
sBuffer.append(cStr[i]);
sBuffer.append("#");
}
//id表示回文中心。max表示最右回文边界。p[]表示当前位置最大回文半径
int id =0;
int max = 0;
int p[]= new int[sBuffer.length()];
for (int i = 1; i < sBuffer.length(); i++) {
// 会有三种情况:1. 目前的i被最大回文子串包含,所以 p[i]=p[2*id-i]<max-i 不超过max则。
// 2. p[2*id-i]>max-i,则p[i]=max-i。否则与max现在位置矛盾。
// 3.p[2*id-i]=max-i,则超出max部分的部分需要暴力匹配
if (i<max) {
p[i] = Math.min(p[2*id-i], max-i);
}else {
p[i]= 1;
}
//暴力匹配过程。
while (i-p[i]>=0&&i+p[i]<sBuffer.length()&&sBuffer.charAt(i-p[i])==sBuffer.charAt(i+p[i])) {
p[i]++;
}
//如果i+p[i]>max,则更新max与id
if (i+p[i]>max) {
max = i+p[i];
id = i;
}
}
int maxl = 0 ;
int maxid =0 ;
for(int i =0 ;i<p.length;i++){
if(maxl<p[i]){
maxl=p[i];
maxid = i;
}
}
//maxl为最大回文长度,id至max。相当于原字符串长度+1
int r = maxl-1;
int start = maxid-r+1;
int end = maxid+r;
StringBuffer out = new StringBuffer();
for (int i = start; i < end; i++) {
if (sBuffer.charAt(i)!='#') {
out.append(sBuffer.charAt(i));
}
}
System.out.println("最大回文子串长度:"+ (r)+"\n内容为:"+out.toString());
return r;
}
}
参考博客:http://blog.csdn.net/xingyeyongheng/article/details/9310555
http://www.bilibili.com/video/av4829276/ 视频讲解有误,但是能够帮助理解。 讲解中p[2*id-i]>max-i时说i的右侧未知可能存在匹配是不准确的,超出部分一定不回文,否则max的长度应该更长,与已知结果矛盾,所以p[i]应该等于max-i。 当p[2*id-i]=max-i,则超出max部分的部分需要暴力匹配