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;
}
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;
}
相关文章推荐
- hdu 3374 String Problem 【kmp+最小(大)表示法】
- HDU 3374 KMP +字符串最小表示
- hdu 3374 String Problem(KMP+字符串最小最大表示)
- hdu 3374 String Problem (kmp+最大最小表示法)
- HDU 3374 String Problem (KMP+最大最小表示法)
- HDU 3374 String Problem (KMP+最大最小表示)
- 【KMP】 HDU 3374 String Problem 最小表示法
- String Problem - HDU 3374 (kmp+最大最小表示)
- HDU 3374 String Problem(字符串最小表示+KMP )
- HDU 3374 String Problem (KMP+最大最小表示)
- HDU 3374 String Problem (KMP+最大最小表示)
- HDU 3374 String Problem (KMP+最大最小表示)
- HDU 3374 String Problem (KMP+最小最大表示)
- hdu 3374 String Problem (kmp+最大最小表示法)
- HDU 3374 String Problem (KMP+最大最小表示)
- HDU 3374 KMP 最大表示法 最小表示法
- hdu 3374 String Problem(最小表示法+kmp)
- hdu 3374 String Problem kmp+字符串最小表示法+next数组性质
- HDU 3374 String Problem(最大最小表示法模板+KMP+next数组的运用)
- HDU 3374 String Problem (KMP+最大最小表示)