Reproduced:
O(N)Palindrome string algorithm Here, I introduce a method of O (n) palindrome string processing. Manacher algorithm.
Original address:
http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindrome-sub-string/
In fact, the original words are more clear, just English, I write a Chinese here.
First of all: we all know what is called Palindrome string bar, this algorithm to solve is a string of the longest palindrome substring how long. This algorithm can be used in the time complexity of O (n) in the case of linear time complexity, to find out how long the longest palindrome with each character,
This algorithm has a very clever place, it takes the odd palindrome string and even the palindrome string unifies to consider. This has always been a problem in the issue of palindrome is more annoying place. This algorithm also has a very good place is to make full use of character matching particularity, avoid a large number of unnecessary duplicate matching.
This is the approximate process of the algorithm. First insert a separator between each of the two adjacent characters, which, of course, does not appear in the original string. Can be separated by ' # ' generally. It's very ingenious to combine odd-length palindrome strings with even-numbered palindrome strings (see the following example, the length of the palindrome string is all odd), and then use a secondary array p to record the longest palindrome string with each character centered on the information. P[id] records the longest palindrome string centered on the character Str[id], and when Str[id] is the first character, the longest palindrome string extends the p[id character to the right.
Original string: W AA bwsw F D
Auxiliary array p:1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
Here is a very good property, P[id]-1 is the length of the palindrome string in the original string (including ' # '). If this is not particularly clear, you can take out the paper to draw a picture, their own experience. Of course, everyone here may not be the same, but I think the general idea should be the same.
All right, let's go. The key question now is how to find the P array in O (n) time complexity. As long as the P array to find out, the longest palindrome string can be directly swept out.
Since this algorithm is linear in the past backward sweep. So when we are ready to seek p[i], I have been p[j before. We use MX in the palindrome string before I, and extend to the far right position. At the same time, use the variable ID to record the ID value of the optimal MX. (Note: In order to prevent character comparisons, I added another special character ' $ ' before the string that added ' # ', so the new string subscript is starting at 1)
OK, here, we can put a code in first.
void PK ()
{
int i;
int mx = 0;
int id;
For (I=1 i<n; i++)
{
if (mx > i)
p[i] = MIN (p[2*id-i), mx-i);
else
p[i] = 1;
for (; Str[i+p[i]] = = Str[i-p[i]]; p[i]++)
;
if (P[i] + i > mx)
{
mx = p[i] + i;
id = i;
}}}
The code is not very short, and quite good to write. It's convenient, remember the algorithm I mentioned above avoids a lot of unnecessary duplicate matches. What does this mean, in fact, this is a code.
if (mx > i) p [i] = MIN (P [2 * id-i], mx-i);
When the furthest length of the current face is Mx>i, P[i] has a minimum value. The core idea of this algorithm is here, why does the P array satisfy such a property? (The following sections are picture forms)
After reading this algorithm, you may find out where the algorithm will be used. In fact, the palindrome string suffix array can also be done. Only the complexity is O (n log n), and generally do not deliberately to card a log n algorithm. But just hdu have such a problem, you use the suffix array to write how to get T (of course I write too bad). If you don't believe it, you can try the question. http://acm.hdu.edu.cn/showproblem.php?pid=3068
————————————————————————————————————————————————————————— attach POJ 3974&hdu 3068 manacher algorithm code
#include <map> #include <set> #include <list> #include <queue> #include <deque> #include &l t;stack> #include <string> #include <time.h> #include <cstdio> #include <math.h> #include
<iomanip> #include <cstdlib> #include <limits.h> #include <string.h> #include <iostream>
#include <fstream> #include <algorithm> using namespace std; HDU 3068 #define LL long #define MIN int_min #define MAX int_max #define PI acos ( -1.0) #define FRE freopen ("input.t
XT "," R ", stdin) #define FF freopen (" Output.txt "," w ", stdout) #define N 210010 Char str[n];
int p[n];
Char S[n];
void pk (int n) {int i,j;
int mx = 0;
int id;
for (i = 1; i < n; i++) {if (mx > i) {p[i] = min (p[2*id-i], mx-i);
else p[i] = 1;
for (; Str[i-p[i]] = = Str[i + p[i]]; p[i]++);
if (P[i] + i > mx) {mx = p[i] + i;
id = i;
}
}} void Gao (int n) {int i,j;
int mx = 0;
for (i = 1; i < n; i++) {if (P[i] > mx) {mx = p[i];
} printf ("%d\n", mx-1);
int main () {while (scanf ("%s", s+1)!=-1) {int i,j;
int len = strlen (s+1);
Str[0] = ' @ ';
Str[1] = ' # ';
for (i = 2, j = 1; j <= Len; j + +) {str[i++] = s[j];
str[i++] = ' # ';
} Str[i] = ';
cout<<str<<endl;
PK (i);
Gao (i);
return 0; }
#include <map> #include <set> #include <list> #include <queue> #include <deque> #include &l t;stack> #include <string> #include <time.h> #include <cstdio> #include <math.h> #include
<iomanip> #include <cstdlib> #include <limits.h> #include <string.h> #include <iostream>
#include <fstream> #include <algorithm> using namespace std; POJ 3974 #define LL long #define MIN int_min #define MAX int_max #define PI acos ( -1.0) #define FRE freopen ("input.t
XT "," R ", stdin) #define FF freopen (" Output.txt "," w ", stdout) #define N 2000020 Char str[n];
int p[n];
Char S[N/2];
void pk (int n) {int i,j;
int mx = 0;
int id;
for (i = 1; i < n; i++) {if (mx > i) {p[i] = min (p[2*id-i], mx-i);
else p[i] = 1;
for (; Str[i-p[i]] = = Str[i + p[i]]; p[i]++);
if (P[i] + i > mx) {mx = p[i] + i;
id = i;
} } void Gao (int n) {int i,j;
int mx = 0;
for (i = 1; i < n; i++) {if (P[i] > mx) {mx = p[i];
} printf ("%d\n", mx-1);
int main () {int CA = 1;
while (scanf ("%s", s+1)) {if (strcmp (s+1, "end") = = 0) break;
int i,j;
int len = strlen (s+1);
Str[0] = ' @ ';
Str[1] = ' # ';
for (i = 2, j = 1; j <= Len; j + +) {str[i++] = s[j];
str[i++] = ' # ';
} Str[i] = ';
printf ("Case%d:", ca++);
PK (i);
Gao (i);
return 0; }