最大回文字符串

问题描述:

求一段字符串中最大的回文子串,比如字符串c1 = 123456789aaabbbccccccbbbddd987654321,最大的回文子串就是bbbccccccbbb

 

问题解答:

之前使用后缀树来找过最长公共子串问题(可参考我之前的bloghttp://www.cnblogs.com/L-aho/articles/2444768.html),在这里同样可以利用上。需要做的就是再反向复制原有子串c2 = 123456789dddbbbccccccbbbaaa987654321,针对这个字符串同样建立一棵后缀树。使用qsort来对两棵后缀树进行排序操作,我们就能分别得到下面的结构:

1、对于两边的字符串再分别使用两个指针指向起始的位置

2、求出二者从起始字母开始有多少重合部分,并且再判断二者在原字符串中是否属于回文字符串,比如第二行的左边123456789和右边的123456789重合,但是在原字符串中并不是回文字符串,抛弃。

3、比较两边的大小,小的一边指针往下移动,继续2的操作,直到最后结束

 

下面为C代码描述:

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  #define MAXN 50000

  int comlen(char* p, char* q)
  {
      int i = 0;
      while (*q && (*p++ == *q++))
      {
          i++;
      }
      return i;
  }

  int cstring_cmp(const void *a, const void *b)
  {
      const char **ia = (const char **)a;
      const char **ib = (const char **)b;
      return strcmp(*ia, *ib);
  }

  int main()
  {
      char c[MAXN];
      char* a[MAXN];

      char ch;
      int n = 0;
      while ((ch = getchar()) != EOF)
      {
          a[n] = &c[n];
          c[n++] = ch;
      }


      //相对于a的一个反向的后缀树
      char* b[MAXN];
      char c2[MAXN];
      for (int i = 0; i < n - 1; i++)
      {

          c2[i] = c[n -2 - i];
          b[i] = &c2[i];
      }
      b[n - 1] = 0;

      qsort(a, n - 1, sizeof(char*), cstring_cmp);
      qsort(b, n - 1, sizeof(char*), cstring_cmp);

      int an = 0;
      int bn = 0;
      int ref = -1;
      int maxlen = 0;
      int maxi = 0;
      int maxib = 0;
      int len = 0;
      //启动
      len = comlen(a[an], b[bn]);
      if ((an + len) == (strlen(b[bn])))
      {
          maxlen = len;
          maxi = an;
      }
      ref = strcmp(a[an], b[bn]);
      if (ref == 1)
      {
          bn++;
      }
      else
      {
          an++;
      }


      while (an < n - 1 && bn < n - 1)
      {
          len = comlen(a[an], b[bn]);
          if ((maxlen < len) && ((n - strlen(a[an])) + len) == (strlen(b[bn])))
          {
              maxlen = len;
              maxi = an;

              maxib = bn;
          }

          //继续比赛
          ref = strcmp(a[an], b[bn]);
          if (ref == 1)
          {
              bn++;
          }
          else
          {
              an++;
          }
      }


      printf("maxlen:%d\tmax string:\t", maxlen);
      char ch_tmp;
      for (int i = 0; i < maxlen; i++)
      {
          ch_tmp = *(a[maxi] + i);
          printf("%c", ch_tmp);
      }
      printf("\n");

      return 0;
  }

posted on 2012-05-09 15:57  aho  阅读(1488)  评论(1编辑  收藏  举报

导航