您的位置:首页 > 其它

hdu 3374 最小表示法加 KMP

2012-08-11 16:43 387 查看
用最小表示法求最小表示和最大表示的位置。然后用KMP匹配字符串出现的次数。

str=s+s;

#include<iostream>

#include<string>

#include<stdio.h>

using namespace std;

char str[2000005];

char a[2000005];

int next[2000005];

int min_str(char* a,int& len_str);

int max_str(char* a);

int kmp(char *a,char *b);

void slove(char *s);

int main()

{

int i,j,k;

int n;

while(scanf("%s",str)!=EOF)

{

int len=strlen(str);

for(i=0;i<len;i++)

str[len+i]=str[i];

str[len+i]=0;

int ttt;

int minp=min_str(str,ttt)+1;

int maxp=max_str(str)+1;

for(i=0;i<len;i++)

a[i]=str[minp-1+i];

a[len]=0;

slove(a);

int mint=kmp(a,str+1);

for(i=0;i<len;i++)

a[i]=str[maxp-1+i];

a[len]=0;

slove(a);

int maxt=kmp(a,str+1);

printf("%d %d %d %d\n",minp,mint,maxp,maxt);

}

return 0;

}

void slove(char *s)

{

int i,j,len=strlen(s);

next[0]=0;j=0;

for(i=1;i<len;i++)

{

while(j>0&&s[j]!=s[i])j=next[j-1];

if(s[j]==s[i])j++;

next[i]=j;

}

}

int kmp(char *a,char *b)

{

int i,j=0,lena=strlen(a),lenb=strlen(b),c=0;

for(i=0;i<lenb;i++)

{

while(j>0&&a[j]!=b[i])j=next[j-1];

if(a[j]==b[i])j++;

if(j==lena){j=next[j-1];c++;}

}

return c;

}

int min_str(char* a,int& len_str)

{

int p1=0;

int p2=1;

int k=0;

int t;

int len=strlen(a);

while(p1<len/2&&p2<len/2&&k<len/2)

{

t=a[(p1+k)]-a[(p2+k)];

if(t==0)

k++;

else

{

if(t<0)

p2+=k+1;

else

p1+=k+1;

if(p1==p2)

p2++;

k=0;

}

}

int min=p1>p2?p2:p1;

int max=p1<p2?p2:p1;

len_str=max-min;

return min;

}

int max_str(char* a)

{

int p1=0;

int p2=1;

int k=0;

int t;

int len=strlen(a);

while(p1<len/2&&p2<len/2&&k<len/2)

{

t=a[(p1+k)]-a[(p2+k)];

if(t==0)

k++;

else

{

if(t>0)

p2+=k+1;

else

p1+=k+1;

if(p1==p2)

p2++;

k=0;

}

}

int min=p1>p2?p2:p1;

return min;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: