hdu4749 kmp改进

这题说的是给了一个模板串 然后又给了一个串 需要找出类似的按个模板串 , 改相等的位置要相等 该大于的位置到大于

我们将模板串做好失配指针就ok了,然后匹配和原来的匹配不同,这个匹配需要的是相对匹配,只要他们的相对位置相同就ok了,每次计算要插入的数在这个匹配中的排位

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn=100005;
int x[maxn],a[maxn],D[26];
int F[maxn];
void getFail(int m)
{
     F[1]=1; F[2]=1;
     for(int i=2; i<=m; i++)
        {
            int j=F[i];
            while( j != 1 && a[i] != a[j]) j = F[ j ];
            F[i+1]=( a[i] == a[j] )? j+1 : 1;
        }
}
int perx[maxn][26],pera[maxn][26];
void init(int n, int m,int k)
{
     memset(perx[0],0,sizeof(perx[0]));
     memset(pera[0],0,sizeof(pera[0]));
     for(int i=1; i<=n; i++)
        {
            for(int j=0; j<=k; j++)
             perx[i][j]=perx[i-1][j];
            perx[i][ x[i] ]++;
        }
     for(int i=1; i<=m; i++)
     {
         for(int j=0; j<=k; j++)
             pera[i][j]=pera[i-1][j];
         pera[i][a[i]]++;
     }
}
bool vis[maxn];
bool jul(int xi, int aj)
{
    int mii=0,ei=0,mij=0,ej=0;
    for(int k=0; k<x[xi]; k++)
        mii+=perx[xi][k]-perx[xi-aj][k];
    ei=perx[xi][ x[xi] ] - perx[ xi - aj ][ x[ xi ] ];
    for(int k=0; k<a[ aj ]; k++)
        mij+=pera[ aj ][ k ];
    ej=pera[ aj ][ a[aj] ];
    return mii==mij&&ej==ei;
}
void find(int n,int m)
{
    int j=1;
    for(int i=1; i<=n; i++)
        {
            while(j!=1&&jul(i,j)==false)j=F[j];
            if(jul(i,j))j++;
            if( j == m + 1 )
                {
                    vis[ i ]=true;j=F[j];
                }
        }
}
int main()
{
    int n,m,k;
    while(scanf("%d%d%d",&n,&m,&k)==3)
    {
        memset(D,0,sizeof(D));
        for(int i=1; i<=n; i++)
            {
                scanf("%d",&x[i]);
                vis[i]=false;
            }
        for(int i=1; i<=m; i++)
            {
                scanf("%d",&a[i]);
                D[a[i]]=1;
            }
        for(int i=1; i<=k; i++)
            D[i]=D[i]+D[i-1];
        for(int i=1; i<=m; i++)
            a[i]=D[a[i]];
        getFail(m);
        init(n,m,k);
        find(n,m);
        int ans=0,loc=m;
        while(loc<=n){
            if(vis[loc]){
                ans++;
                loc+=m;
            }else loc++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-11-15 07:06:13

hdu4749 kmp改进的相关文章

KMP改进(nextval)

为什么要对next进行改进呢?因为next存在缺陷...O(∩_∩)O哈哈~... 什么缺陷呢? 课上老师PPT中的那个例子不太好,并没有把核心体现出来,只是一部分,所以请结合课件和下面的例子仔细体会. 设 S串     abcabdabcabcd : P串   abcabcd 好了,先求出P串的next[],(听话,求出next[],别看了,让你在自己电脑上把next求出来,不会的话,代码在上一篇博客(http://www.cnblogs.com/xiaoshanshan/p/4081693.

hdu4749 kmp应用

呃,从网上看的题解,然而其实有点地方还没搞懂,先放在这,以后再回来理解. 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目:2013 is the 60 anniversary of Nanjing University of Science and Technology, and today happens to be the anniversary date. On this happy festival, school autho

模式串匹配--KMP算法

  前几天百度LBS部门实习二面,让写一个字符串匹配函数,当时忘记KMP怎么写了,就默默的写了一个暴力搜索,连尝试推导一下KMP都没有,结果自然是没有过,以后面试要多和面试官交流,就算忘记了,也要让他知道你试图推导,要不然他会觉得你可能都没有听过. KMP是对前缀暴力搜索的改进,基于的想法其实是很朴素的.首先我们来看一下暴力搜索. char* BF(char *src, char *pattern){ if(src == NULL || pattern == NULL) return NULL;

第十一章&#183;串

ADT 定义:字符串,是指来自于某个字母表的字符组成的有限序列. 数据结构:可以由向量或者列表来实现. 特点:相对于一般的线性序列,串具有更鲜明的特征:其组成字符很少,串的长度却高出几个数量级. 几个术语: 空串是任何串的子串.前缀和后缀 任何串是其自身的子串.前缀和后缀 长度严格小于原串的子串.前缀和后缀也称为真子串.真前缀和真后缀 作为一个ADT,其标准接口如下 length用于获取串S的长度 charAt(i)用于获取指定字符在串S中的位置 substr(i,k)用于获取串S中从i到k的子

KMP及其改进算法

本文主要讲述KMP已经KMP的一种改进方法.若发现不正确的地方,欢迎交流指出,谢谢! KMP算法的基本思想: KMP的算法流程: 每当一趟匹配过程中出现字符比较不等时,不需回溯 i 指针,而是利用已经得到的部分匹配的结果将模式向右滑动尽可能远的一段距离后,继续进行比较. 设S为目标串,T为模式串,设 i 指针和 j 指针分别指示目标串和模式串中正待比较的字符. 开始时,令i=0,j=0.如果Si==Tj,则使i和j的值分别增加l:反之,i不变,j的值退回到j=next[j]的位置(即模式串右滑)

KMP算法及其改进

KMP算法及其改进 字符串匹配算法也就是从一个很长的字符串里面找出与我们手中的字符串相匹配的字符串(是这个大字符串的第几个字符开始),对于这个问题我们有很简单的解法,叫BF算法,Brute Force也就是蛮力的意思,充分依靠计算能力来解决问题的方法,对于这种解法可以用下面的图片来表述: 上面的算法就是BF算法,不好之处是效率太低了,因为就像第三趟比较中那样,我们只有最后一个元素没有匹配上就要从头再来,主串的对应元素竟然要回头从第四个元素开始比较,我们明明比较到了主串的第七个元素,前面的工作全部

模式串匹配、KMP算法及其改进(代码)

#include "string.h" #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 100 /* 存

改进KMP模式匹配算法

看了算法的大致步骤,然后自己一一证明了每一步的正确性,注释里写了一些理解. 这也不是新鲜的做法,只是感觉这个程序非常精巧,反复地使用数学归纳法. 让我感觉很新鲜. 1 /* 2 next[i]存放:match[i]处失配,orig在对应位置将要匹配的值 3 按照KMP的思想, 4 即是1到i-1子串中最长相同前后缀的前缀最后一项的后一项 5 且这一项和match[i]不同 6 7 若不存在同缀子串但是第一项与i项不同,值为1. 8 若不存在同缀子串且第一项与i项相同,值为0,即将j向后移动一个位

改进的KMP算法的执行过程

比如有模式串  t="aaaabaac" 首先我们至少光看的话,发现未修正的next数组是很好列出来的 是next:0,1,2,3,4,1,2,3 在这个基础上我们可以很容易的写出修正好的nextVal数组: 设nextVal[1]=0; (1)i=2,看next[i]=next[2]=1=j,因为t[i]==t[j]即t[2]==t[1],所以nextVal[2]=nextVal[1]=0; (2)i=3,next[i]=next[3]=2=j,因为t[2]==t[3],所以next