您的位置:首页 > 编程语言 > C语言/C++

求一个字符串中连续出现次数最多的子串

2015-02-05 15:37 609 查看
         今天看了《程序员面试宝典》中这道题,顺便又看了有关字符串数据结构与算法中的KMP算法,发现网上有关这道题的解法是O(n³),结合自己对KMP中的next数组,写了一个O(n²)的代码。下面说说说的算法。

首先求出字符串S的所有后缀,

如:cababbb的后缀子串

0-cababbb

1-ababbb

2-babbb

3-abbb

4-bbb

5-bb

6-b

因为S一直不变,所以可以用如下方法求

for(int i=0;i<n;i++)
ss[i]=&s[i];
        然后求出每一个,后缀字符串的next数组(KMP中的),再根据next数组计算每一个后缀字符串的以首字母为基准的最多重复子串个数,这和POJ2406题目相似。然后不断更新最大值即可。

       由于没有找到OJ题目,不知道算法正确与否,先写在这里,日后验证。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define N 100
char s
;
char *ss
;
int next[N+1]={0};
using namespace std;
void GetNext(char *sp,int n);
int main()
{
int m;
scanf("%d",&m);
while(m--)
{
int max=1;
scanf("%s",s);
int n=strlen(s);
for(int i=0;i<n;i++)
{
ss[i]=&s[i];
int l=n-i;
GetNext(ss[i],l);
for(int j=1;j<=l;j++)
{
if(j%(j-next[j])==0)
{
int x=j/(j-next[j]);
max=(max>x?max:x);
}
}
}
printf("%d\n",max);
}
return 0;
}
void GetNext(char *sp,int n)
{
int i=0,k=-1;
next[0]=-1;
while(i<n)
{
if(k==-1||sp[i]==sp[k]){
++i;
++k;
next[i]=k;
}
else
k=next[k];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 字符串 KMP next数组