1. 程式人生 > >KMP判斷 串2在串1中出現的次數

KMP判斷 串2在串1中出現的次數

例題

學騷話

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

眾所周知,青春期豬頭少年梓川咲太騷話連篇。

這可讓眾多網友羨慕不已,於是觀眾們紛紛尊稱其為師傅,更有甚者已經開始模仿師傅學習了。

現在給你兩行字元,第一行是師傅梓川咲太的正宗騷話,第二行是某位**網友的模仿。

請問這位網友的騷話完成度是多少?

騷話完成度是指該騷話在原版中的出現次數,在原版中出現時可重疊。

Input

輸入包含多組資料。

每組資料由兩行字串構成,分別表示豬頭少年的正宗騷話和網友的模仿。

字串長度均在1000000以內。

Output

輸出X的最大長度,佔一行 

Sample Input

abababababa
aba
 

Sample Output

5

Hint

Source

行走的二叉樹

 

#include <bits/stdc++.h>
using namespace std;
int nextt[1000005];
int ans;
void get_next(char str2[])  // 構建字首表
{
    int len = strlen(str2);
    nextt[0] = -1;
    int j = -1, i = 0;
    while (i < len)
    {
        if (j == -1 || str2[i] == str2[j])
        {
            i++;
            j++;
            nextt[i] = j;
        }
        else
            j = nextt[j]; // 失配回溯
    }
}
void kmp(char str1[], char str2[])
{
    get_next(str2);
    int len1 = strlen(str1), len2 = strlen(str2);
    int i = 0, j = 0;
    while (i < len1 && j <= len2)
    {
        if (j == 0 || str1[i] == str2[j])
        {
            i++;
            j++;
        }
        else
            j = nextt[j]; // 失配回溯
        if (j == len2)  // j==len2說明匹配上 然後往後挪len2-1個單位 匹配下一次
        {
            ans++;
            j = 0;
            i -= len2 - 1;
        }
    }
}

int main()
{
    char str1[1000005], str2[1000005];
    while (~scanf("%s", str1))
    {
        scanf("%s", str2);
        ans = 0;
        kmp(str1, str2);
        printf("%d\n", ans);
    }
    return 0;
}