1. 程式人生 > >HDOJ2087剪花布條-----KMP演算法模板題

HDOJ2087剪花布條-----KMP演算法模板題

Problem Description

一塊花布條,裡面有些圖案,另有一塊直接可用的小飾條,裡面也有一些圖案。對於給定的花布條和小飾條,計算一下能從花布條中儘可能剪出幾塊小飾條來呢?

Input

輸入中含有一些資料,分別是成對出現的花布條和小飾條,其布條都是用可見ASCII字元表示的,可見的ASCII字元有多少個,布條的花紋也有多少種花樣。花紋條和小飾條不會超過1000個字元長。如果遇見#字元,則不再進行工作。

Output

輸出能從花紋布中剪出的最多小飾條個數,如果一塊都沒有,那就老老實實輸出0,每個結果之間應換行。

Sample Input

abcde a3 aaaaaa aa #

Sample Output

0 3

題意:

給定源字串s和模式字串p,求在s中能截出多少個p,典型的KMP模板題。

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
char s[1024];// 源串
char p[1024];// 目的串
int Next[1024];// Next陣列

// 計算Next陣列
void CalNext() {
    Next[0] = 0;
    Next[1] = 0;
    int len = strlen(p);
    int k = 0;// 上次計算出來的Next值 
    for(int i = 2;i <= len;i++) {
        while(p[i-1] != p[k] && k) {
            k = Next[k];
        }
        if(p[i-1] == p[k]) {
            k++;
        }
        // 不需要對k==0特判
        Next[i] = k;
    }
    
}

// KMP演算法求匹配串個數
int KMP() {
    int i = 0;// 源串指標
    int j = 0;// 模式串指標
    int count = 0;// 返回值
    int len1 = strlen(s);
    int len2 = strlen(p);
    while(i < len1) {
        if(s[i] == p[j]) {
            i++,j++;
            if(j == len2) {
                // 模式串匹配成功
                count++;
                j = 0;
            }
        } else {
            if(j == 0)
                i++;// 避免死迴圈
            j = Next[j];
        }
    }
    return count;
}


int main()
{
   while(scanf("%s",s) != EOF) {
       if(strcmp(s,"#") == 0) {
           break;
       }
       scanf("%s",p);
       printf("%d\n",KMP());
       
   }
   
   return 0;
}