對於字符cabadabae來說,已有的回文有aba, ada,abadaba。最長的顯然是abadaba。如果簡單點要找出最長的回文。可以用遍歷的方式,時間負責度將是O(n^3)。為了降低時間負責度,我們就必須采用另外的方式。由於回文是左右對稱的,因此我們可以利用左右對稱的這個特性來尋找答案
對於字符串cabadabae來說。已經知道了第三位為中心的aba和第5位為中心的abadaba是回文。已知第5位為中心的abadaba是回文,由回文的特性,就能夠知道2-4位和6-8位對稱,而又知道第3位為中心的aba是回文,所以2-4位是回文。這樣的話,6-8位肯定是回文。
那么如果我們要判斷第6位為中心的回文的時候,該如何進行呢
cabadabae 3-4於6-7位對稱
cabadabae 而第四位的a回文長度為1
cabadabae 可以推斷出第6位的回文長度也是1
那么也就是說以第6位為中心的回文其實不需要擴展,我們可以直接知道回文長度為1。那么以第7位為中心的回文是否需要向兩邊擴展繼續尋找呢。答案是需要的。因為我們已經知道6-8位是回文,也就是以第7位為中心的回文長度至少為3。但是第9位是什么不知道,因此需要擴展邊界。
對應代碼如下:
char *insertsymtostring(char *s)
{
char *newstr;
int len,len1,i,j;
len = strlen(s);
len1 = 2 * len - 1;
j = 0;
newstr = (char *)malloc(len1 * sizeof(char));
for (i = 0; i < len1; i+=2)
{
newstr[i] = s[j];
newstr[i + 1] = '#';
j++;
}
newstr[i-1] = '\0';
return newstr;
}
char *reverfindLongestPlalindromeStringseKGroup(char *s)
{
char *s1,*s2;
int i,len,rightside,rightsidecenter,center,longesthalf, needCalc,j;
rightside = rightsidecenter = 0;
center = longesthalf = 0;
int *halflenarr;
//將字符之間插入#
s1 = insertsymtostring(s);
len = strlen(s1);
halflenarr = (int *)malloc(len * sizeof(int));
memset(halflenarr, 0, len*sizeof(int));
s2 = (char *)malloc(len*sizeof(char));
j = 0;
for (i = 0; i < len; i++)
{
needCalc = 1;
if (rightside > i)
{
//回到與之對稱的左邊符號位置,根據對稱的左邊符號的回文長度得到當前的回文長度
int leftcenter = 2 * rightsidecenter - i;
halflenarr[i] = halflenarr[leftcenter];
if (i + halflenarr[i] > rightside)
{
halflenarr[i] = rightside - i;
}
//如果擴展后的邊界小於回文的最大邊界rightside, 則表明不需要擴展邊界
if (i + halflenarr[leftcenter] < rightside)
{
needCalc = -1;
}
}
//計算以每個字符為中心的回文長度,計算右邊界和center位置。halflenarr存儲回文長度的一半
if (needCalc == 1)
{
while (i - 1 - halflenarr[i] >= 0 && i + 1 + halflenarr[i] < len)
{
if (s1[i + 1 + halflenarr[i]] == s1[i - 1 - halflenarr[i]])
{
halflenarr[i]++;
}
else
break;
}
rightside = i + halflenarr[i];
rightsidecenter = i;
if (halflenarr[i] > longesthalf)
{
center = i;
longesthalf = halflenarr[i];
}
}
}
//根據當前得到的重點位置和最大回文長度的一般,來得到回文字符
for (i = center - longesthalf; i <= center + longesthalf; i += 2)
{
s2[j] = s1[i];
j++;
}
printf("center=%d\n", center);
printf("center_value=%c\n", s1[center]);
printf("longesthalf=%d\n",longesthalf);
s2[j] = '\0';
printf("s2=%s\n", s2);
return s2;
}