A - Oulipo

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book:

Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l’air normal mais…

Perec would probably have scored high (or rather, low) in the following contest. People are asked to write a perhaps even meaningful text on some subject with as few occurrences of a given “word” as possible. Our task is to provide the jury with a program that counts these occurrences, in order to obtain a ranking of the competitors. These competitors often write very long texts with nonsense meaning; a sequence of 500,000 consecutive 'T's is not unusual. And they never use spaces.

So we want to quickly find out how often a word, i.e., a given string, occurs in a text. More formally: given the alphabet {'A''B''C', …, 'Z'} and two finite strings over that alphabet, a word W and a text T, count the number of occurrences of W in T. All the consecutive characters of W must exactly match consecutive characters of T. Occurrences may overlap.

Input

The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:

  • One line with the word W, a string over {'A''B''C', …, 'Z'}, with 1 ≤ |W| ≤ 10,000 (here |W| denotes the length of the string W).
  • One line with the text T, a string over {'A''B''C', …, 'Z'}, with |W| ≤ |T| ≤ 1,000,000.

Output

For every test case in the input file, the output should contain a single number, on a single line: the number of occurrences of the word W in the text T.

Sample Input

3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN

Sample Output

1
3
0

纯KMP算法,KMP确实是神算法。。一开始我还没弄懂就开始敲,居然把长字串给求next值了,KMP其妙是在其求的出现的重复字串的next值,当失配时,只需要回溯到第一个重复字串(后面的都是重复前面的字串)的相应失配位置,再开始匹配就行,不需要从头开始。。这样就把一个嵌套的循环活生生的改成了一个O(n)的时间复杂度。

KMP的实现主要是两步

1.求next数组的值。

我的前提是字串读取为从0开始到len-1位置。

先定义next[0]为0(也有定义为-1的,我的习惯是0)。

从1到len-1循环,

定义i为循环变量,顺便定义j为next数组的循环变量(j=0初始),当s[i]==s[j]时,说明出现重复字串,则j++;

如果不相等,则说明此处失配,但是!!!注意:失配不代表当前next值就为0,需回溯到该失配处对应的上一处重复点,

即while(j>0&&s[i]!=s[j])j=next[j-1];(这里需要着重说明,因为刚刚坑也坑在这里,因为此时j处失配,因此通过next[j-1]回溯到之前,但正好由于数组下标比实际数位小1,因此得到的next[j-1]值正好就是失配点对应的回溯点,不用再+1了,当然如果一直失配下去,j最终为0)

要是比较难理解这个失配点的回溯点是怎么回事,我们看个例子:

ID 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  
str a b a b c a b a b a b a b c a b a b  
Next 0 0 1 2 0 1 2 3 4 3 4 3 4 5 7 7 8 9  

我们可以看到,着重注意一下下标为9的点,此时s[i=9]!=s[j=4] 则,找回溯点 j=next[j-1=3]=2,即失配前一个字符对应的回溯点告诉我们 失配点的回溯点的下标为2,则此时 s[j=2]==s[i=9],即匹配成功,说明回溯过去,找到了失配点的一个配对点。但注意,一旦配对成功,(有一种情况是回溯过去,找不到配对点,j直接=0,之后不做处理),但如果配对成功了,说明相对于j=2,该点是j=2之后的又一配对点,所以j++,使得j要=3;故此时next[9]=3;

2.匹配过程

1.匹配是从另一个长串开始循环(定义循环变量为i,长串为ls),另一个循环变量q=0则负责s。

初始i s均为0,若ls[i]==s[q] 则 :q++,i++;

如果不等,则s需要回答其失配点对应的回溯点,当然如果q==0,则没有回溯点可言,故直接i++;否则 q=next[q-1](为什么是q-1和上述相同);

。。。。此处进行很多次循环;

当q==len;说明此时已经匹配完成,ans++;(说明匹配到一个字串) 并且 q=next[q-1](原理相同,将q回到末尾点的回溯点的下一点,与ls[i](此时i已经递增一位)继续进行匹配)。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char w[];
char t[];
int next[];
int ans;
void kmp_1()//求next数组过程
{
next[]=;
int j=;
for (int i=; w[i]!='\0'; i++)//用w[i]!='\0',就不用测算w的长度,减少时间
{
if (w[i]==w[j])
{
j++;
}
else
{
while (j>&&w[i]!=w[j])
j=next[j-];
if (w[i]==w[j]) //确实找到了匹配的回溯点,说明next值可以+1了.
j++;
}
next[i]=j;
}
}
void kmp_2()//匹配过程
{
int k,q;
ans=;
for (k=,q=; t[k]!='\0';)
{
if (t[k]==w[q])
{
q++;
k++;
}
else
{
if (q==) k++;
else
q=next[q-];
}
if (w[q]=='\0')
{
ans++;
q=next[q-];
}
}
}
int main()
{
int tt;
scanf("%d",&tt);
getchar();
while (tt--)
{
memset(next,,sizeof next);
gets(w);
gets(t);
int lenw;
//lenw=strlen(w);
kmp_1();
kmp_2();
printf("%d\n",ans);
}
return ;
}
 

poj_3461 KMP算法解析的更多相关文章

  1. KMP算法解析(转自图灵社区)

    KMP算法是一个很精妙的字符串算法,个人认为这个算法十分符合编程美学:十分简洁,而又极难理解.笔者算法学的很烂,所以接触到这个算法的时候也是一头雾水,去网上看各种帖子,发现写着各种KMP算法详解的转载 ...

  2. KMP算法解析

    介绍一种高效的KMP算法:代码可以直接运行 #include <iostream> #include <iomanip> using namespace std; void p ...

  3. 字符串匹配的KMP算法详解及C#实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  4. KMP串匹配算法解析与优化

    朴素串匹配算法说明 串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. 为了更好理解KMP算法,我们先这样看待一下朴素匹配算法吧.朴素 ...

  5. KMP算法深入解析

    本文主要介绍KMP算法原理.KMP算法是一种高效的字符串匹配算法,通过对源串进行一次遍历即可完成对字符串的匹配. 1.基础知识的铺垫 字符串T的前k(0 =< k <=tlen)个连续的字 ...

  6. 经典串匹配算法(KMP)解析

    一.问题重述 现有字符串S1,求S1中与字符串S2完全匹配的部分,例如: S1 = "ababaababc" S2 = "ababc" 那么得到匹配的结果是5( ...

  7. 不能更通俗了!KMP算法实现解析

    我之前对于KMP算法理解的也不是很到位,如果很长时间不写KMP的话,代码就记不清了,今天刷leetcode的时候突然决定干脆把它彻底总结一下,这样即便以后忘记了也好查看.所以就有了这篇文章. 本文在于 ...

  8. Java数据结构之字符串模式匹配算法---KMP算法

    本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基 ...

  9. KMP算法具体解释(转)

    作者:July. 出处:http://blog.csdn.net/v_JULY_v/. 引记 此前一天,一位MS的朋友邀我一起去与他讨论高速排序,红黑树,字典树,B树.后缀树,包含KMP算法,只有在解 ...

随机推荐

  1. windowsService 程序

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. ReadyBoost 的应用教程

    一.什么是ReadyBoost 根据百度百科介绍,ReadyBoost是存在于Windows Vista中的一项新技术,在继Vista的下一代操作系统Windows 7中,同样包 含着这项技术,它利用 ...

  3. Ubuntu 19.10将使用GCC 9作为默认编译器

    作为我们这一周期一直期待的变化,Ubuntu 19.10升级到GCC 9作为GCC 8的默认系统编译器. Ubuntu 19.10(和Ubuntu 20.04 LTS)将使用GCC 9 stable作 ...

  4. SpringMVC一点简单地源码解析

    . 1.1 init(初始化) 在第一次发出请求时,会调用HttpServletBean 的init()方法 org.springframework.web.servlet.HttpServletBe ...

  5. shell教程——bash入门

    创建shell文件 vim test.sh 写内容 #!/bin/bash echo "Hello World !" 使脚本具有执行权限 chmod +x ./test.sh 执行 ...

  6. vue 【 子子组件 => 子组件 => 父组件 】 的事件和参数的传递

    1,子子组件  TodoItem.vue     <template>   <div class="todo-item" :class="{'is-co ...

  7. 解题报告:luogu P5020(NOIP 2018 D1T2)

    题目链接:P5020 货币系统 \(NOIP\) 的题挺精华啊. 开始感觉自己有隐约的思路,但感觉太暴力,连数据范围都没看,就去看题解了(不会啊). 听说是\(dp\)又是一惊,直接弃疗. 其实只是个 ...

  8. MongoDB首次启动常见问题

    问题1. exception in initandlisten 29 data directory /data/db not found 问题:MongoDB默认存储路径为/data/db,这里显示没 ...

  9. JavaScript 的一些SAO操作

    IE判断检测 jQuery 在 1.9 版本之前,提供了一个浏览器对象检测的属性 .browser 的替代方案.于是各种利用 IE bug 的检测方法被搜了出来: // IE 678 最短方法 var ...

  10. window 如何访问虚拟机的mapreduce(遇到的坑)

    首先 先把你虚拟机和本机网络链接弄通 (详情看上一篇)  一些关于mapreduce 和hadoop的配置都在上一篇 安装eclipse 的hadoop Map/Reduce插件详情 看其他博客园.. ...