找出字符串中的最長迴文

對於字符cabadabae來講,已有的迴文有aba, ada,abadaba。最長的顯然是abadaba。若是簡單點要找出最長的迴文。能夠用遍歷的方式,時間負責度將是O(n^3)。爲了下降時間負責度,咱們就必須採用另外的方式。因爲迴文是左右對稱的,所以咱們能夠利用左右對稱的這個特性來尋找答案ide

對於字符串cabadabae來講。已經知道了第三位爲中心的aba和第5位爲中心的abadaba是迴文。已知第5位爲中心的abadaba是迴文,由迴文的特性,就可以知道2-4位和6-8位對稱,而又知道第3位爲中心的aba是迴文,因此2-4位是迴文。這樣的話,6-8位確定是迴文。字符串

 

那麼若是咱們要判斷第6位爲中心的迴文的時候,該如何進行呢string

cabadabae             3-4於6-7位對稱擴展

cabadabae             而第四位的a迴文長度爲1遍歷

cabadabae             能夠推斷出第6位的迴文長度也是1時間

那麼也就是說以第6位爲中心的迴文其實不須要擴展,咱們能夠直接知道迴文長度爲1。那麼以第7位爲中心的迴文是否須要向兩邊擴展繼續尋找呢。答案是須要的。由於咱們已經知道6-8位是迴文,也就是以第7位爲中心的迴文長度至少爲3。可是第9位是什麼不知道,所以須要擴展邊界。while

對應代碼以下:字符

 

char *insertsymtostring(char *s)new

{return

    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;

}

相關文章
相關標籤/搜索