hduoj2087 统计串t在串s中出现的次数,重叠不算 KMP

hduoj2087 统计串t在串s中出现的次数,重叠不算  KMP

C - 剪花布条
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 
 

Input

输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。 
 

Output

输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。 
 

Sample Input

abcde
a3
aaaaaa
aa
#
 

Sample Output

0
3
思路:每次去掉匹配过的串以及在其前面的字符,继续匹配,统计次数。采用指针操作字符串更方便。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=(1<<29);
const double EPS=0.0000000001;
const double Pi=acos(-1.0);

char s[maxn],t[maxn];
int Next[maxn];

void get_next(char* t)
{
    int i=0,j=-1;
    Next[0]=-1;
    int m=strlen(t);
    while(i<m){
        if(j==-1||t[i]==t[j]) Next[++i]=++j;
        else j=Next[j];
    }
}

int kmp(char* s,char *t)
{
    int i=0,j=0;
    int n=strlen(s),m=strlen(t);
    while(i<n&&j<m){
        if(j==-1||s[i]==t[j]) i++,j++;
        else j=Next[j];
    }
    if(j==m) return i-m;
    else return -1;
}

int main()
{
    while(scanf("%s",s)&&strcmp(s,"#")){
        scanf("%s",t);
        int ans=0;
        char *s1=s;
        get_next(t);
        while(1){
            int tmp=kmp(s1,t);
            if(tmp!=-1){
                ans++;
                s1+=tmp+strlen(t);
                if(s1>=s+strlen(s)) break;
            }
            else break;
        }
        cout<<ans<<endl;
    }
}
View Code

 

posted @ 2015-06-05 18:14  __560  阅读(1098)  评论(0编辑  收藏  举报