[Hiho]1015-KMP算法

题目:
输入

第一行一个整数N,表示测试数据组数。

接下来的N*2行,每两行表示一个测试数据。在每一个测试数据中,第一行为模式串,由不超过10^4个大写字母组成,第二行为原串,由不超过10^6个大写字母组成。

其中N<=20
输出

对于每一个测试数据,按照它们在输入中出现的顺序输出一行Ans,表示模式串在原串中出现的次数。
Sample Input

5
HA
HAHAHA
WQN
WQN
ADA
ADADADA
BABABB
BABABABABABABABABB
DAD
ADDAADAADDAAADAAD

Sample Output

3
1
3
1
0

Solution:
需要稍加改造KMP算法,因为有重叠的现象,所以需要将模式串的next数组往后再计算一位,比如ADA,首尾是一样的,那就计算ADAX,X所在next数,这样重叠现象也可解决。

#include<iostream>
#include<string>

using namespace std;
int * BuildNext(string pattern)
{
    int n = pattern.size();
    int* next = new int[n+1];
    int k = -1;
    next[0] = -1;
    int j = 0;
    while(j < n)
    {
        if(k == -1 || pattern[j] == pattern[k])
        {
            k++;
            j++;
            if( j == n || pattern[j] != pattern[k])
            {
                next[j] = k;
            }
            else
                next[j] = next[k];
        }
        else
            k  = next[k];
    }

    return next;
}

int Search(string pattern,string original)
{

    int n = original.size();
    int *next = BuildNext(pattern);
    int j = 0;
    int count = 0;
    for(int i = 0;i<original.size();i++)
    {
        if(j > 0 && pattern[j] != original[i])
        {
            j = next[j];
            if(j == -1)
                 j = 0;
        }
        if(pattern[j] == original[i])
            j++;
        if(j == pattern.size())
        {
            count++;
            j = next[j];
            if(j == -1)
                j = 0;
        }
    }

    return count;
}


int main()
{
    char rows;
    int row = 0;
    int i,j,k;
    i = j = k = 0;
    cin>>row;
    string* pattern = new string[row];
    string* original = new string[row];
    for(i = 0;i<row;i++)
    {
            cin>>pattern[i];
            cin>>original[i];
    }
    for(i = 0;i<row;i++)
    {
        int count  = Search(pattern[i],original[i]);
        cout<<count<<endl;
    }
    return 0;
}

你可能感兴趣的:(算法,hiho)