• 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);
        }
    }
  • 相关阅读:
    chrome 开发者工具
    iOS-登陆界面 实现光标换行功能
    iOS-UIkit复习和代理的使用实现文本框限制输入字数控制
    iOS-代理模式
    ios-疯狂猜图
    ios-状态栏的改变
    iOS-应用管理 点击按钮下载动画
    ios-利用xib重新写 应用管理
    ios-应用管理 字典转模型
    ios-应用管理
  • 原文地址:https://www.cnblogs.com/Hilda/p/2659111.html
Copyright © 2020-2023  润新知