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部分的部分需要暴力匹配