Longest reply string
Algorithm idea:
String s [] = "121"
Step 1:By adding a special character to the left and right of each character, the string with an odd or even length is converted into an odd number (for example. "121" with special characters to "#1 #2 #1"), you can also add a special character at the beginning, in this way, we can ignore the out-of-bounds issue (for example, "121" is changed to "$ #1 #2 #1 #". The special character $ at this time and the \ 0 at the end of the string are all other characters in this string. different, you can ignore the out-of-bounds issue). In this case, the string becomes
S [] = "$ #1 #2 #1 #"
Step 2:V [I] array represents the length (including s [I]) of the longest I-centered substring in string s to the left or right.
In this case, the correspondence between s [] and v [] is
S [] =$ #1 #2 #1 #
V [] = 1 2 1 4 1 2 1
We can see that the maximum value-1 in v [] is the total length of the longest retrieval string 4-1 = 3.
Implementation Method:
Add two auxiliary variables cn and mx. cn indicates the center position of the maximum echo substring, and mx indicates cn + v [cn], that is, the boundary of the maximum echo substring. An important conclusion is given: If mx> I, then v [I]> = min (v [2 * cn-I], mx-I)
Proof:
Scenario 1: When mx-I> v [2 * cn-1, the substring centered on s [2 * cn-1] is contained in the substring centered on s [cn], and because I and 2 * cn-1 are symmetric, the substring centered on s [I] must be contained in the string centered on s [cn, v [I] = v [cn * 2-1] ()
Case 2: When mx-I <= v [2 * cn-1, the echo substrings centered on v [2 * cn-I] may not be completely contained in the ECHO substrings centered on v [cn], but according to Yi Zhi: the parts enclosed by the blue box are the same. That is to say, the v [I]-centered echo substring is expanded to at least the mx position to the right, that is, v [I]> = mx-I. Check whether the parts after mx are symmetric.
The above two cases can be implemented by the following code:
V [I] = mx> I? Min (v [cn * 2-I], mx-I): 1; while (s [I + v [I] = s [I-v [I]) // check whether the mx part matches ++ v [I].
Overall implementation code:
#include <stdio.h>#define min(a, b) (a > b ? b : a)int LPS(char *p){char s[10000] = "$#";int v[10000] = {0};int c = 1;while (*p){s[++c] = *p++;s[++c] = '#';}s[++c] = '\0';int mx = 0, cn = 0, re = 0;for (int i = 1; '\0' != s[i]; ++i){v[i] = mx > i ? min(v[cn * 2 - i], mx - i) : 1;while (s[i + v[i]] == s[i - v[i]])++v[i];if (i + v[i] > mx){cn = i;mx = i + v[i];}if (v[i] > re)re = v[i];}return re - 1;}int main(){char s[10000];while (~scanf("%s", s)){printf("%d\n", LPS(s));}return 0;}
Copyright statement: This article is the original author article, reprint please indicate the source http://blog.csdn.net/xianyun2009