ZOJ 3643 Keep Deleting【KMP+栈模拟】

Assume that string A is the substring of string B if and only if we can find A in B, now we have a string A and another string B, your task is to find a A in B from B's left side to B's right side, and delete it from B till A is not a substring of B, then output the number of times you do the delete.

There are only letters(A-Z, a-z) in string A and B.

Input

This problem contains multiple test cases. Each case contains two line, the first line is string A, the second line is string B, the length of A is less than 256, the length of B is less than 512000.

Output

Print exactly one line with the number of times you do the delete for each test case.

Sample Input

abcd

abcabcddabcdababcdcd

Sample Output

5

Hint

abcabcddabcdababcdcd delete=0

abcdabcdababcdcd     delete=1

abcdababcdcd         delete=2

ababcdcd             delete=3

abcd                 delete=4

                     delete=5



题目大意:给出a和b串,a是b串的子串,如果b串有连续的a串,那么就将b串的a串删除,问删除多少次;
思路:栈的模拟思想,每个字符入栈,如果出现和串a相同的子串那么相同的字串退栈;剩下的字符继续入栈;但是暴力的找很消耗时间,因此用到KMP;
  例如 串a:abcd 串b:abcabcdd
  在b串中找到了a串,但是应该跳道德是abc串的c那里看下一个字符是否是d;所以先用KMP的=求出串a的next[]数组的值;

代码如下:

栈写的代码:

View Code
#include<stdio.h>

#include<string.h>

#include<iostream>

#include<stack>

using namespace std;

#define N 512005

char cha[N], chb[N];

int next[N];

int main()

{

    int i, j, lena, lenb, t, ans;

    while(scanf("%s%s", cha+1, chb+1)!=EOF)

    {

        lena=strlen(cha+1), lenb=strlen(chb+1);

        memset(next, 0, sizeof(next));

        next[1]=0, j=0;

        stack<int>s;

        for(i=2; i<=lena; i++)

        {

            while(j&&cha[j+1]!=cha[i])

                j=next[j];

            if(cha[j+1]==cha[i])

                j++;

            next[i]=j;

        }

        j=0, ans=0;

        for(i=1; i<=lenb; i++)

        {

            while(j&&cha[j+1]!=chb[i])

                j=next[j];

            if(cha[j+1]==chb[i])

                j++;

            s.push(j);

            if(j==lena)

            {

                ans++;

                for(t=0;t<lena;t++)

                    s.pop();

                if(!s.empty())

                    j=s.top();

                else

                    j=0;

            }

        }

        printf("%d\n", ans);

    }

}

数组模拟栈代码:

View Code
#include<stdio.h>

#include<string.h>

#include<iostream>

using namespace std;

#define N 512005

char cha[N], chb[N];

int next[N], stack[N];

int main()

{

    int i, j, lena, lenb, t, ans, tt;

    while(scanf("%s%s", cha+1, chb+1)!=EOF)

    {

        lena=strlen(cha+1), lenb=strlen(chb+1);

        memset(next, 0, sizeof(next));

        memset(stack, 0, sizeof(stack));

        next[1]=0, j=0;

        for(i=2; i<=lena; i++)

        {

            while(j&&cha[j+1]!=cha[i])

                j=next[j];

            if(cha[j+1]==cha[i])

                j++;

            next[i]=j;

        }

        j=0, ans=0, tt=0;

        for(i=1; i<=lenb; i++)

        {

            while(j&&cha[j+1]!=chb[i])

                j=next[j];

            if(cha[j+1]==chb[i])

                j++;

            stack[tt++]=j;

            if(j==lena)

            {

                ans++;

                for(t=0;t<lena;t++)

                    tt--;

                if(tt==0)

                    j=0;

                else

                    j=stack[tt-1];

            }

        }

        printf("%d\n", ans);

    }

}

你可能感兴趣的:(KMP)