ZOJ 3643 kmp+栈处理失配指针

当kmp在母串中匹配到子串之后,删去子串相当于把失配指针往回退到匹配位置的前一个,如果只回退一次的话,直接用数组就可以处理失配指针了,但是本题可能删除后存在多个子串,所以用栈把失配指针位置先存起来,然后找到一次把len长度的失配指针删去,然后栈顶元素就是第一句话说的回退出匹配位置的前一个了。

为了方便调用函数,把以前的kmp改成了接口,方便使用,这样就不用开全局变量的数组了,代码看起来更符合工作中开发的代码风格。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define sc(a,b) scanf("%d%d",&a,&b)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 400005
#define MN 100005
#define INF 1000000007
#define eps 1e-7
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void fail(char *ss,int *next)
{
    int k=-1,j=0,len=strlen(ss);
    next[0]=-1;
    while(j<len)
    {
        if(k==-1||ss[j]==ss[k])
        {
            j++,k++;
            if(ss[j]!=ss[k]) next[j]=k;
            else next[j]=next[k];
        }
        else k=next[k];
    }
}
int kmp(char *substr,char *str)
{
    stack<int>s;
    int next[260];
    fail(substr,next);
    int i=-1,j=-1,sum=0;
    int len=strlen(str),lensub=strlen(substr);
    while(i<len)
    {
        if(j==-1||substr[j]==str[i])
        {
            i++,j++,s.push(j);
            if(j==lensub)
            {
                sum++;
                for(int ii=0; ii<lensub; ii++) s.pop();
                j=s.top();
            }
        }
        else j=next[j];
    }
    return sum;
}
int main()
{
    static char substr[270],str[510005];
    while(~scanf("%s%s",substr,str))
    {
        pri(kmp(substr,str));
    }
    return 0;
}

ZOJ 3643 kmp+栈处理失配指针,布布扣,bubuko.com

时间: 2024-10-11 06:26:30

ZOJ 3643 kmp+栈处理失配指针的相关文章

POJ 2752 深刻理解KMP失配指针

思路:刚开始还在想怎么做,虽然以前是理解了失配指针的用处,但是确实不知道失配指针还有如此用处,其实还有很多用处,我用得少了不懂而已. 比如: i   0  1  2  3  4  5   6  7  8  9  10 11 p[i]  A  B R A  C  A  D  A  B  R  A  无 next[i]  0  0  0  0  1  0   1  0  1   2  3   4 next[11]=4这个肯定可以取了,因为这个后缀等于前缀嘛,然后再查询next[next[11]]=n

C 提高1 内存四区 变量本质 栈开口方向 指针铁律1

C 提高第一天复习 内存四区,变量常量的本质,函数调用模型,栈开口方向,指针铁律1,指针是一种数据类型 C 提高学员标准:写一个标准的冒泡排序 选择法或者冒泡法排序 在一个函数内排序 通过函数调用的方式排序 数组做函数参数的技术盲点和推演 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int i = 0; int j = 0; int tmp = 0; int a[] = 

zoj 2615 Cells 栈的运用

题目链接:ZOJ - 2615 Scientists are conducting research on the behavior of a newly discovered Agamic Cellular Microbe. This special kind of microbe is capable of massively reproducing by itself in a short time. The lifetime of an ACM consists of three pha

C利用可变参数列表统计一组数的平均值,利用函数形式参数栈原理实现指针运算

//描述:利用可变参数列表统计一组数的平均值 #include <stdarg.h> #include <stdio.h> float average(int num, ...);//函数原型:即声明 float average2(int num, ...);//num个数 void add(int num, int x, int y, int z); int main(void){ int a=10; int b=20; printf("a地址:%p b地址:%p\n&

内存的堆分配和栈分配 &amp; 字符数组,字符指针,Sizeof总结

堆和栈的区别 一个由C/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵.3.全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻

ZOJ Problem Set - 3643 Keep Deleting

题目大意: 给出a和b串,a是b串的子串,如果b串有连续的a串,那么就将b串的a串删除,问删除多少次: 题目分析: 打比赛的时候没敲出来,后来想到用栈的思想去模拟就行,网上还有用KMP+栈去做的,没有KMP,也能AC,一会去学习一下KMP算法 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #include<algorithm> 6 #

数据结构--KMP算法总结

数据结构—KMP KMP算法用于解决两个字符串匹配的问题,但更多的时候用到的是next数组的含义,用到next数组的时候,大多是题目跟前后缀有关的 . 首先介绍KMP算法:(假定next数组已经学会,后边next数组会在介绍) 上图T为主链,P为模板链,要求P在T中是否出现,出现就返回位置. 朴素算法会顺序遍历,比较第一次的时候p[0]处失配,然后向后移动继续匹配.数据量大的时候这么做肯定是不可行的.所以这里就会有KMP算法!在一次失配之后,KMP算法认为这里已经失配了,就不能在比较一遍了,而是

HDU1711(KMP)

Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22739    Accepted Submission(s): 9727 Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b

BZOJ_3670_[NOI2014]_动物园(kmp)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3670 对于一个字符串,求出num数组,其中num[i]表示前i个字符构成的字串中不相重合的相同前后缀共有多少对. 分析 在做kmp的自匹配时,顺便记录一个cnt数组,其中cnt[i]表示第i个字符需要进行几次i=fail[i]到达0,也就是如果失配时跳转到i位置,包括i位置,之前共有多少可以作为失配时跳转对象的(也就是有多少满足和后面某一后缀相同的前缀).第二遍做子匹配时,将失配指针一直跳到