zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    C# List的深复制(转)
    asp.net core控制台项目运行
    进度条界面控件
    给窗体做遮罩(另类做法)
    显示列表控件(引用SourceGrid)
    TimeExit 界面无点击定时退出类
    TimeHelp 获取时间戳转换类
    复旦大学2016--2017学年第一学期高等代数I期末考试情况分析
    复旦大学高等代数历届每周一题汇总
    复旦高等代数 I(16级)每周一题
  • 原文地址:https://www.cnblogs.com/Hilda/p/2659111.html
Copyright © 2011-2022 走看看