Manacher算法。最大回文子串。


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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章