zoukankan      html  css  js  c++  java
  • 【KMP】BZOJ3942-[Usaco2015 Feb] Censoring

    【题目大意】

    有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。输出最后的S串。

    【思路】
    三天前写过一次,用的是以前的KMP模板,但是觉得太乱了,数组下标一会儿是下标一会儿是长度,傻傻分不清。参照其他人常见的方法重改了一发,算是比较清晰的KMP了,所有数组下标均直接指代字符串下标。

    维护两个同进同出的栈,s代表当前的U串,a代表在s串种相应位置时的j指针位于模式串中的下标。每次将匹配串的下一位压入s中,用KMP判断匹配。一旦成功匹配到一个,便从栈中弹出即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=1000000+50;
     7 char p[MAXN],t[MAXN],s[MAXN];
     8 int next[MAXN],a[MAXN],len,lenp;
     9 
    10 void getnext()
    11 {
    12     int i=0,j=-1;
    13     next[i]=j;
    14     for (int i=1;i<len;i++)
    15     {
    16         while (j!=-1 && p[i]!=p[j+1]) j=next[j];
    17         if (p[i]==p[j+1]) ++j;
    18         next[i]=j;
    19     }
    20 }
    21 
    22 void solve()
    23 {
    24     int top=0;
    25     for (int i=0;i<len;i++)
    26     {
    27         int j=a[top];
    28         s[++top]=t[i];
    29         while (j!=-1 && p[j+1]!=s[top]) j=next[j];
    30         if (p[j+1]==s[top]) ++j;
    31         a[top]=j;
    32         if (a[top]==lenp-1) top-=lenp;
    33     }
    34     s[top+1]='';
    35     puts(s+1);
    36 }
    37 
    38 int main()
    39 {
    40     scanf("%s%s",t,p);
    41     len=strlen(t),lenp=strlen(p);
    42     getnext();
    43     solve();
    44     return 0;
    45 }
  • 相关阅读:
    KindEditor简单的Demo使用
    动态从数据库读取菜单(ASP.NET版)
    完全卸载sql2005
    关于在xp(sp3 专业版)下安装sql2005开发版图解
    新手上路Tomcat 7.x和JDK的配置
    关于IE6幽灵字体
    【译】写个好的 CLI 程序
    【译】通过 Rust 学习解析器组合器 — Part 1
    【译】PHP 内核 — zval 基础结构
    【译】PHP 内核 — 字符串管理
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5710297.html
Copyright © 2011-2022 走看看