[week15] C - ZJM与纸条(选做)—— KMP算法

2023-05-16

文章目录

  • 题意
    • Input
    • Output
    • 输入样例
    • 输出样例
    • 提示
  • 分析
  • 总结
  • 代码

题意

ZJM 的女朋友是一个书法家,喜欢写一些好看的英文书法。有一天 ZJM 拿到了她写的纸条,纸条上的字暗示了 ZJM 的女朋友 想给 ZJM 送生日礼物。ZJM 想知道自己收到的礼物是不是就是她送的,于是想看看自己收到的礼物在纸条中出现了多少次。

Input

第一行输入一个整数代表数据的组数

每组数据第一行一个字符串 P 代表 ZJM 想要的礼物, 包含英语字符 {‘A’, ‘B’, ‘C’, …, ‘Z’}, 并且字符串长度满足 1 ≤ |P| ≤ 10,000 (|P| 代表字符串 P 的长度).
接下来一行一个字符串 S 代表 ZJM 女朋友的纸条, 也包含英语字符 {‘A’, ‘B’, ‘C’, …, ‘Z’}, 满足 |P| ≤ |S| ≤ 1,000,000.

Output

输出一行一个整数代表 P 在 S中出现的次数.

输入样例

3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN

输出样例

1
3
0

提示


分析

这也是一道用KMP算法解决的字符串问题。


  • KMP算法

1. KMP算法的作用

KMP算法是用来求一个字符串在另一个字符串中出现的次数,或是所有出现的位置。

如:abbabab中bab出现的次数为2。分别为第3-5个字符和第5-7个字符。显然子串在字符串中出现的不同位置可以有部分重复。

其中用来匹配的子串被称作模式串,被匹配的长字符串为主串。

2. next数组

next数组是实现KMP算法的关键。

next[i]存储的是字符串中从开头到下标为i的这一段子串中,首尾相同字符串的长度。

如,abcabc:

  • 在该字符串中,第一个字符(下标为0)到倒数第二个字符(下标为4)这一段的字符串中,首尾存在相同的字符串ab,因此next [4] = 2
  • 第一个字符(下标为0)最后一个字符(下标为5)这一段的字符串中,首尾存在相同的字符串abc,因此next [5] = 3
  • 其余部分构成的字符串中,首尾都不存在相同部分,因此都为0。

3. KMP算法

算法过程如下:

  • 从主串和模式串的首部开始依次扫描每一个字符
  • 若当前主串扫描的字符和模式串扫描的字符相同,则模式串指针后移
  • 若当前二者扫描的字符不同,则开始转移:
    • 主串指针不变
    • 模式串的指针从当前匹配失败处转移为指向下标等于当前指向字符的前一个字符所对应的next数组中存储长度的字符
    • 循环转移,直到回到模式串首部,或转移后指针指向字符与主串指向字符匹配成功
  • 若模式串被扫描完,则说明已经在主串中找到一个模式串,出现次数+1或执行对应操作
  • 主串指针后移

4. 求next数组

next数组完全可以用KMP算法求得。也就是模式串自己匹配自己来获得next数组。

从模式串的第一个和第二个字符开始匹配,即主串从第二哥字符开始扫描,模式串从第一个字符开始。因为对第一个字符来说不存在首尾部分。

在这个匹配过程中,模式串和主串相同。其中模式串扫描的部分就相当于是原字符串中的首部分,而被匹配的主串与模式串所匹配的部分就是原字符串中的尾部分。

也就是用字符串每一个首部分与其每一个尾部分匹配(首尾部分最长就为前半部分和后半部分),来得到第一个字符开始到每一个字符结尾所构成的字符串中的首尾相同子串的长度。

next的使用原理:

假设主串和模式串中第 i 个字符匹配失败,若next[i] = p。
则第i个字符的前p个字符与模式串的前p个字符完全相同,那么将模式串移动,直到第i个字符的前p个字符与模式串前p个字符一一对应。
那么显然,接下来要从主串的第i个字符和模式串的第p + 1个字符开始继续进行匹配。

而模式串重新开始扫描字符在字符串数组的下标就等于p(若从下标为0处开始存储),因此next数组是用来重新定位模式串扫描起点的。


  • 题目分析

这道题就是利用KMP算法解决。只要理解了KMP算法,就可以很好解决。这道题是用该算法求出现次数。


总结

  1. 这个算法的难点在于理解next数组的计算过程。但是稍微思考一下还是没啥问题的。

代码

//
//  main.cpp
//  lab3
//
//

#include <iostream>
#include <string>
using namespace std;

int Next[10002];

void get_next(string s1,int length)     //得到next数组
{
    Next[0] = 0;
    
    for( int i = 1 , j = 0 ; i < length ; i++ )     //遍历模式串,自己与自己进行匹配
    {
        while( j && s1[i] != s1[j] )
            j = Next[j - 1];
        
        if( s1[i] == s1[j] )
            j++;
        
        Next[i] = j;
    }
}

int kmp(string s1,string s2)        //kmp
{
    int res = 0;
    
    get_next(s2,s2.size());     //得到模式串的next数组
    
    for( int i = 0,j = 0 ; i < s1.size() ; i++ )        //遍历主串
    {
        //若匹配失败
        //从模式串中当前匹配失败字符的前一个字符的next数组所对应的字符开始重新匹配
        while( j && s1[i] != s2[j] )
            j = Next[j - 1];
        
        //匹配成功,模式串向后扫描
        if( s1[i] == s2[j] )
            j++;
        
        //若模式串被完整扫描,则说明主串包含模式串
        if( j == s2.size() )
        {
            res++;                  //包含模式串的个数+1
            j = Next[j - 1];        //主串向后继续扫描
        }
    }
    return res;
    
}



int main()
{
    ios::sync_with_stdio(false);
    
    int t = 0;
    cin>>t;
    
    while( t-- )
    {
        string s1,s2;
        cin>>s2>>s1;
        
        cout<<kmp(s1, s2)<<endl;
    
    }
    
    return 0;
}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[week15] C - ZJM与纸条(选做)—— KMP算法 的相关文章

  • 数据结构串的基本操作及KMP算法

    将串的基本操作C语言实现 xff0c 实现KMP算法算出NEXT函数和NEXTVAL的值 SqString h的基本内容 span class hljs keyword typedef span span class hljs keywor
  • w15作业--ZJM 与霍格沃兹(必做)

    题意 xff1a ZJM 为了准备霍格沃兹的期末考试 xff0c 决心背魔咒词典 xff0c 一举拿下咒语翻译题 题库格式 xff1a 魔咒 对应功能 背完题库后 xff0c ZJM 开始刷题 xff0c 现共有 N 道题 xff0c 每道
  • Week15 实验

    A Q 老师的记录册 Problem Statement Q 老师有 N 个学生 xff0c 每个学生都有各自独立的编号 xff0c 且编号范围在 1 N 之间 这一天 xff0c 所有学生都在不同的时间进入教室 Q 老师记录了当编号为 i
  • A - ZJM 与霍格沃兹 (Week15 作业)

    A ZJM 与霍格沃兹 Sample Input expelliarmus the disarming charm rictusempra send a jet of silver light to hit the enemy tarant
  • TT数鸭子 && ZJM要抵御宇宙射线(M4)

    TT数鸭子 题目描述 这一天 xff0c TT因为疫情在家憋得难受 xff0c 在云吸猫一小时后 xff0c TT决定去附近自家的山头游玩 TT来到一个小湖边 xff0c 看到了许多在湖边嬉戏的鸭子 xff0c TT顿生羡慕 此时他发现每一
  • week15实验

    文章目录 A题目要求代码 B题目要求代码 C题目要求代码 D题目要求代码 E题目要求代码 F题目要求代码 A 题目要求 Q 老师有 N 个学生 xff0c 每个学生都有各自独立的编号 xff0c 且编号范围在 1 N 之间 这一天 xff0
  • week15作业A ZJM 与霍格沃兹

    ZJM 为了准备霍格沃兹的期末考试 xff0c 决心背魔咒词典 xff0c 一举拿下咒语翻译题 题库格式 xff1a 魔咒 对应功能 背完题库后 xff0c ZJM 开始刷题 xff0c 现共有 N 道题 xff0c 每道题给出一个字符串
  • KMP算法

    一 何谓模式串匹配 模式串匹配 xff0c 就是给定一个需要处理的文本串 xff08 理论上应该很长 xff09 和一个需要在文本串中搜索的模式串 xff08 理论上长度应该远小于文本串 xff09 xff0c 查询在该文本串中 xff0c
  • 【Week 15 作业B】ZJM与生日礼物

    题目描述 ZJM 收到了 Q老师 送来的生日礼物 xff0c 但是被 Q老师 加密了 只有 ZJM 能够回答对 Q老师 的问题 xff0c Q老师 才会把密码告诉 ZJM Q老师 给了 ZJM 一些仅有 01 组成的二进制编码串 他问 ZJ
  • 【Week 15 作业C】ZJM与纸条

    题目描述 ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM 送生日礼物 ZJM 想知道自己收到的礼物是不是就是她送的 xff0
  • 【Week16实验 B】ZJM要抵御宇宙射线【模拟】

    题意 xff1a 思路 xff1a 对每个点都求出到其余点的距离平方 xff0c 然后取该点到其他点的距离平方的最大值为半径平方 xff0c 最后对所有点的半径平方取最小值 注意有多解时将x较小 y较小的点作为答案 总结 xff1a 一道简
  • 9.KMP算法

    KMP算法 1 KMP算法解决的问题 字符串str1和str2 xff0c str1是否包含str2 xff0c 如果包含返回str2在str1中开始的位置 xff0c 如果不包含返回 1 如果做到时间复杂度O N 完成 xff1f 测试用
  • Cyclic Nacklace 【HDU - 3746】【KMP补周期】

    KMP算法的讲解 自己的领悟可随时提问 题目链接 题意 有一个字符序列 现在问你 序列后面最少补充几个元素使其恰能成为几个重复循环的序列 题目还是很良心的 让我们求字符串后面放几个字符可以使其变成周期字符串 所以还是可以想到用KMP的nex
  • KMP算法原理详解_论文解读版

    1 KMP算法 KMP算法是一种保证线性时间的字符串查找算法 由Knuth Morris和Pratt三位大神发明 而算法取自这三人名字的首字母 因而得名KMP算法 那发明这样的字符串查找算法又有什么用 在当时计算机本身非常昂贵 计算资源更是
  • 使用共享 MVI 架构实现高效的 Kotlin Multiplatform Mobile (KMM) 开发

    使用共享 MVI 架构实现高效的 Kotlin Multiplatform Mobile KMM 开发 文章中探讨了 Google 提供的应用架构指南在多平台上的实现 通过共享视图模型 View Models 和共享 UI 状态 UI St
  • kmp算法(最简单最直观的理解,看完包会)

    本文将以特殊的方式来让人们更好地理解kmp算法 不包括kmp算法的推导 接下来 我们将从朴素算法出发 在这之前 我们先设主串为S 模式串为T 我们要解决的询问是主串中是否包含模式串 即T是否为S的子串 版权声明 本文为原创文章 转载请标明出
  • 数据结构中Java实现KMP与BF算法对比

    public class KMPANDBF public int indexBfCount SeqString s SeqString t int begin int slen tlen i begin j 0 int count 0 sl
  • Oulipo

    点击打开链接 Problem Description The French author Georges Perec 1936 1982 once wrote a book La disparition without the letter
  • Period 【HDU - 1358】【KMP求周期】

    学习KMP算法可以参阅这篇文章 不懂的可以在线回答 题目链接 题意 我们想知道一串字符中的前缀中有多少最大周期数 例如 aaa 中 前两个 aa 最小周期长度为 a 所以周期长度为2 前三个 aaa 的最小周期也是 a 所以周期长度为3 再
  • KMP比较简单的讲法。

    转载链接 http blog csdn net yearn520 article details 6729426 我们在一个母字符串中查找一个子字符串有很多方法 KMP是一种最常见的改进算法 它可以在匹配过程中失配的情况下 有效地多往后面跳

随机推荐

  • 华为IS-IS基础配置

    目录 一 原理概述 二 实验要求 三 实验拓扑 四 实验步骤 一 原理概述 1 IS IS xff1a Intermediate System to Intermediate System xff0c 中间系统到中间系统 2 链路状态协议
  • 基于markdown-it打造的markdown编辑器

    前言 markdown it是一个用来解析markdown的库 xff0c 它可以将markdown编译为html xff0c 然后解析时markdown it会根据规则生成tokens xff0c 如果需要自定义 xff0c 就通过rul
  • WiFi模块ESP-07s开发过程(学习笔记)

    目录 注意事项获取AT指令用到的指令通过返回的指令提取自己想要的信息 注意事项 转义字符 xff1a xff1a C中定义了一些字母前加 34 34 来表示常见的那些不能显示的ASCII字符 xff0c 如 0 t n等 xff0c 就称为
  • Vue3 table表格使用axios调用后端Api数据,统一返回格式

    1 安装axios npm install axios 2 封装axios span class token keyword import span span class token namespace axios span span cl
  • 关于C++的string字符串拼接问题(和“字符转字符串”问题有关)

    xff08 只有气到我肺都炸了的情况下我才可能废一些时间去写博客 xff08 主要是写一些气话 xff09 xff0c 但现在气消得差不多了我也骂不出什么话了 正文 1 字符串拼接分软拼接和硬拼接 xff08 软硬拼接 是我自己发明的词 实
  • [week2]化学——识别烷烃基

    文章目录 题意InputOutput输入样例输出样例 分析总结代码 题意 化学很神奇 xff0c 以下是烷烃基 假设如上图 xff0c 这个烷烃基有6个原子和5个化学键 xff0c 6个原子分别标号1 6 xff0c 然后用一对数字 a b
  • [week2]模拟OJ成绩排名系统(简易版)

    文章目录 题意InputOutput输入样例输出样例 分析总结代码 题意 题面宛如小作文233 程序设计思维作业和实验使用的实时评测系统 xff0c 具有及时获得成绩排名的特点 xff0c 那它的功能是怎么实现的呢 xff1f 我们千辛万苦
  • [week3]区间选点问题——贪心算法

    目录 题意InputOutput输入样例输出样例 分析总结代码 题意 数轴上有 n 个闭区间 a i b i 取尽量少的点 xff0c 使得每个区间内都至少有一个点 xff08 不同区间内含的点可以是同一个 xff09 Input 第一行1
  • [week3]区间覆盖问题——贪心算法

    目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 数轴上有 n 1 lt 61 n lt 61 25000 个闭区间 ai bi xff0c 选择尽量少的区间覆盖一条指定线段 1 t xff08 1 lt 61 t
  • [csp模拟1]咕咕东的奇遇——(一)

    目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 咕咕东是个贪玩的孩子 xff0c 有一天 xff0c 他从上古遗迹中得到了一个神奇的圆环 这个圆环由字母表组成首尾相接的环 xff0c 环上有一个指针 xff0c 最
  • Linux挂载镜像的一些命令

    Linux挂载镜像的一些命令 在Linux中 xff0c 可以用losetup命令来设置无分区空白镜像到loop设备上 xff0c 用kpartx 来kpartx映射分区的镜像到loop设备上 之后通过mount命令将loop设备与系统文件
  • [week5]平衡字符串——尺取法

    目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 一个长度为 n 的字符串 s xff0c 其中仅包含 Q W E R 四种字符 如果四种字符在字符串中出现次数均为 n 4 xff0c 则其为一个平衡字符串 现可以将
  • [csp模拟2]T4——咕咕东的奇妙序列

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 咕咕东 正在上可怕的复变函数 xff0c 但对于稳拿A Plus的 咕咕东 来说 xff0c 她早已不再听课 xff0c 此时她在睡梦中 突然想到了一个奇怪的无限
  • [week9]签到题(长凳)——贪心算法

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 SDUQD 旁边的滨海公园有 x 条长凳 第 i 个长凳上坐着 a i 个人 这时候又有 y 个人将来到公园 xff0c 他们将选择坐在某些公园中的长凳上 xff
  • [week14] Q老师与十字叉

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 Q老师 得到一张 n 行 m 列的网格图 xff0c 上面每一个格子要么是白色的要么是黑色的 Q老师认为失去了 十字叉 的网格图莫得灵魂 一个十字叉可以用一个数对
  • [week15] ZJM 与霍格沃兹 —— 字符串哈希

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 为了准备霍格沃兹的期末考试 xff0c 决心背魔咒词典 xff0c 一举拿下咒语翻译题 题库格式 xff1a 魔咒 对应功能 背完题库后 xff0c ZJ
  • [week14] D - Q老师染砖(选做) —— 矩阵快速幂优化DP

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 衣食无忧的 Q老师 有一天突发奇想 xff0c 想要去感受一下劳动人民的艰苦生活 具体工作是这样的 xff0c 有 N 块砖排成一排染色 xff0c 每一块砖需要
  • [week14] E - Q老师度假(选做)—— 矩阵快速幂优化DP(拓展)

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 忙碌了一个学期的 Q老师 决定奖励自己 N 天假期 假期中不同的穿衣方式会有不同的快乐值 已知 Q老师 一共有 M 件衬衫 xff0c 且如果昨天穿的是衬衫 A
  • [week15] B - ZJM与生日礼物(选做)—— 字典树

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 收到了 Q老师 送来的生日礼物 xff0c 但是被 Q老师 加密了 只有 ZJM 能够回答对 Q老师 的问题 xff0c Q老师 才会把密码告诉 ZJM
  • [week15] C - ZJM与纸条(选做)—— KMP算法

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM