Manacher algorithm first attempt

Mancher parsing algorithm


Reference article

https://blog.csdn.net/qq_32354501/article/details/80084325?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
https://blog.csdn.net/u014771464/article/details/79120964

Manacher algorithm is an algorithm used to solve the string palindrome, the most primitive method of time complexity of O (n3) converted to O (n), the following will be given of two methods for solving the palindromic sequence

The most primitive way

Directly on the code

public static void main(String[] args) 
	{
		String str = "sdffttrrgfddfh";
        String result1=longestPalindrome1(str);//暴力破解算法
        System.out.println(result1);
	}
	public static String longestPalindrome1(String s)
	{
		if(s.length()<=1)
			return s;
		for(int i=s.length();i>0;i--)
		{
			for(int j=0;j<s.length()-i;j++)
			{
				String sub=s.substring(j,i+j);
				int count=0;//匹配个数
				for(int k=0;k<sub.length()/2;k++)
				{
					if(sub.charAt(k)==sub.charAt(sub.length()-k-1))
						count++;
				}
				if(count==sub.length()/2)
					return sub;
			}
		}
		return null;
	}

Take the form of the use of multiple cycles palindromic substring determination, i.e., when the number of match count = palindromic half the length of the substring, the current return substring; the longest since the beginning, the length gradually decreases, to identify palindrome palindromic sequence is the longest substring

Wherein the code: String sub=s.substring(j,i+j);the evolution of i and j below (only a portion of the code for understanding):
Here Insert Picture Description

Manacher algorithm

Manacher algorithm is an expansion from the center toward both sides of the algorithms rely on an array of auxiliary find the largest palindrome radius, in order to find the longest palindrome substring

Directly on the code

public static void main(String[]args)
	{
		String str="sdffttrrgfddfh";
		System.out.println(manacher(str));
	}
	public static String manacher(String str)
	{
		String sub="$#";
		for(int i=0;i<str.length();i++)
		{
			sub+=str.charAt(i);
			sub+="#";
		}
		sub+="!";
		int id=0,sub_side=0,maxlen=0,maxindex=0;
		/*id代表最大回文子串的中心位置
		  sub_side代表以id为中心的回文子串的边界
		  maxlen代表最大回文子串的长度,maxindex代表相应的索引位置
		*/
		int[]p=new int[sub.length()];//P[i]代表以i为中心的字符串的回文半径
		for(int i=0;i<sub.length();i++)
		{
			p[i]=sub_side>i?Math.min(p[2*id-i],sub_side-i):1;
			while (((i-p[i])>=0)&&((i+p[i])<sub.length()-1)&&(sub.charAt(i+p[i])==sub.charAt(i-p[i])))
				++p[i];
			if(sub_side<i)
			{
				sub_side=i+p[i];
				id=i;
			}
			if(maxlen<p[i])
			{
				maxlen=p[i];
				maxindex=i;
			}
		}
		return str.substring(((maxindex-maxlen)/2),((maxindex-maxlen)/2)+maxlen-1);
	}

Because the parity string length change introduced '#' is added to each intermediate character plus the '$' and '!' Is used as a boundary to prevent cross-border

For example: abaaba character, Manacher first step to turn it into $ # a # b # a # a # b # a # preprocessing!

It should introduce palindromic radius, i.e. palindromic palindromic radius distance from the center of the palindrome border, into code id is the distance sub_side
Here Insert Picture Descriptionp is the bottom row of the array, the representative radius palindromic count # symbol, e.g. palindrome radius position is the second central palindrome # to the third position, i.e. from a second position

Difficult to find p [i] -1 original string is the string radius palindrome

Next comes several cases

The first case
Here Insert Picture Description
the right boundary palindromic wherein mx representative radius centered id, for example
Here Insert Picture Description
the right boundary of the first six characters a, the center of the palindrome fourth character b, i is the i th character

When mx - i> P [j] when the palindromic substring to P [j] centered contained in the palindromic substring to the first id character as the center, since i and j are symmetrical to the i-th character Center palindromic substring

Necessarily included in the palindromic substring in characters for the id of the center, so there must be P [i] = P [j].

The second case
Here Insert Picture Description
when mx - i <= time p [j], to the sub-palindromic p [j] is the radius of the center of the palindrome string to exceeded my left boundary of the center of the character id palindromic substrings (according to symmetric), the symmetry, to

Palindromic substring of p [i] as the center of the character will range beyond the boundary, i.e. it must be extended to re-select the center of the palindrome, this section corresponding to the code

if(sub_side<i)
{
	sub_side=i+p[i];//sub_side相当于mx
	id=i;
}

Re-use of violence to match.

The third case

For mx <= i is the case, not to make the additional assumption P [i], only P [i] = 1, then go to match the violence.

Published an original article · won praise 0 · Views 13

Guess you like

Origin blog.csdn.net/qq_44500864/article/details/105197640