扩展KMP--求母串各后缀和模串的最长公共前缀

来源:互联网 发布:仿生活家家居网站源码 编辑:程序博客网 时间:2024/06/05 22:44

1.next数组,求母串和模串最长公共前缀类似

     next数组是模串程自己的最长公共前缀,如

 

 

 模串为:A A A B C C D D A A A B C C D D A A

  则Next: 0   2 1   0 0   0 0   0 9   2 1   0 0  0 0   0 2  1

 

 

 

    

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

A

A

A

B

C

C

D

D

A

A

A

B

C

C

D

D

A

A

0

2

1

0

0

0

0

0

9

2

1

0

0

0

0

0

2

1

 

next数组求法:

 假设已求出next[0.....k....i - 1],现在要求i,且求出0 + next[0], 1 + next[1] ,2 + next[2].....(i-1 + next[i - 1])中最大为k即是 k + next[k]

1

2

3

4

 

 

代码:

void Next(int *S, int *next, int len)
{
 int i = 0;
 next[0] = 0;
 if (len < 2) return;
 while (S[i] == S[i + 1] && i + 1 < len) i++;
 next[1] = i;
 for (int k = 1, i = 2; i < len; ++i)
 {
  int maxMatch = k + next[k] - 1;
  if (maxMatch < i)
  {//情况1
   int j = 0;
   while (S[j] == S[j + i] && i + j < len) j++;
   k = i;
   next[i] = j;
  }
  else
  {//maxMatch >= i
   if (next[i - k] >= maxMatch - i)
   {//情况2
    int j = maxMatch - i; //i之后的串
    while (S[i + j] == S[j] && i + j < len) j++;
    next[i] = j;
    k = i;
   }
   else next[i] = next[i - k]; //情况3
  }
 }
}

 

 

 

void ExtendKmp(int *S, int *Sub, int *ComPre,int lenS, int lenSub)
{
 int *next = new int[lenSub];
 Next(Sub, next, lenSub);
 int i = 0;
 while (S[i] == Sub[i] && i < lenSub && i < lenS) ++i;
 ComPre[0] = i;
 for (int k = 0, i = 1; i < lenS; ++i)
 {
  int maxMatch = k + ComPre[k] - 1;
  if (maxMatch < i)
  {//情况1
   int j = 0;
   while (S[i + j] == Sub[j] && i + j < lenS && i < lenS) j++;
   k = i;
   ComPre[i] = j;
  }
  else
  {//maxMatch >= i
   if (next[i - k] >= maxMatch - i)
   {//情况2
    int j = maxMatch - i; //i之后的串
    while (S[i + j] == Sub[j] && i + j < lenS && i < lenS) j++;
    ComPre[i] = j;
    k = i;
   }
   else ComPre[i] = next[i - k];//情况3
  }
 }
 //assert(next != NULL);
 delete [] next;
 next = NULL;
}

原创粉丝点击