给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

模板串P在模式串S中多次作为子串出现。

求出模板串P在模式串S中所有出现的位置的起始下标。

输入格式

第一行输入整数N,表示字符串P的长度。

第二行输入字符串P。

第三行输入整数M,表示字符串S的长度。

第四行输入字符串S。

输出格式

共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。

数据范围

1≤N≤1051≤N≤105
1≤M≤1061≤M≤106

 

个人理解:

很多时候我们会遇到字符串匹配的问题,对于数据量很大的字符串时,我们就需要快一点的算法才能支撑这么大的数据。

我们运用暴力算法,就是两个for循环暴力匹配,但是在暴力的同时会做了很多重复的工作。

for (int i = 0; i < m; i++) {
bool flag = true;
for (int j = 0; j < n; j++)
if (s[i + j] != p[j]) {
flag = false;
break;
}
//...........
}

  

所以我们需要用算法优化它,前人就已经为我们想好了思路,我们顺着思路理解它就行。(KMP)

我们要简化时间复杂度肯定要从第二个for循环开始优化,我们发现第二个循环存在重复的情况,例如,第一次用第二重循环错了,没循环完成,然后第二次用也是这种情……直到全对,所以想着把中间无用重复的过程给去。

如何省去这些多余的部呢,模板串可不可以直接跳到合适的的下标呢,而不用每次都从头开始匹配呢??

①对模板串进行处理,用数组标记将前缀与后缀相同的部分关联起来。

②与模式串进行比较,不同就移动到模板串所对应的前下标中,依次继续比较。

详细代码:

#include<iostream>
using namespace std; const int N = , M = ;
char p[N], s[M];
int ne[N]; int main() {
int n, m;
cin >> n >> p + >> m >> s + ; //创建一个临时数组,将模板串的前缀与后缀关联起来。
for (int i = , j = ; i <= n; i++) {
//不同了,我们就得将它退到它前面与现在所相同的部分的下标位置。
while (j && p[i] != p[j + ]) j = ne[j];
//相同了共同前进一个位置。
if (p[i] == p[j + ]) j++;
//做好标记。
ne[i] = j;
} for (int i = , j = ; i <= m; i++) {
//模板串所指的位置与模式串不同了,模板串的下标就要移动到上一个与之相同前缀的位置,再次进行比对,直到相等或者下标为零为止。
while (j && s[i] != p[j + ]) j = ne[j];
//如果相同,共同前进一步。
if (s[i] == p[j + ]) j++;
//模板串全部访问完毕,进行输出。
if (j == n) {
cout << i - n << " ";
//回到上一个与之相同的位置。
j = ne[j];
}
} return ;
}

【算法基础】KMP字符串的更多相关文章

  1. 每周一算法之六——KMP字符串匹配算法

    KMP是一种著名的字符串模式匹配算法,它的名称来自三个发明人的名字.这个算法的一个特点就是,在匹配时,主串的指针不用回溯,整个匹配过程中,只需要对主串扫描一遍就可以了.因此适合对大字符串进行匹配. 搜 ...

  2. 算法基础——Trie字符串统计

    原题链接 题目: 维护一个字符串集合,支持两种操作: "I x"向集合中插入一个字符串x: "Q x"询问一个字符串在集合中出现了多少次. 共有N个操作,输入的 ...

  3. 算法基础——KMP字符串匹配

    原题链接 题目: 给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入 ...

  4. hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)

    基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...

  5. 数据结构与算法--KMP算法查找子字符串

    数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...

  6. KMP算法,匹配字符串模板(返回下标)

    //KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...

  7. 算法:KMP算法

    算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...

  8. BF算法与KMP算法

    BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相等,则比较S的 ...

  9. KMP字符串模式匹配详解(转)

    来自CSDN     A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度 ...

  10. 腾讯2017年暑期实习生编程题【算法基础-字符移位】(C++,Python)

     算法基础-字符移位 时间限制:1秒 空间限制:32768K 题目: 小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间. 你能帮帮小Q吗? ...

随机推荐

  1. Mysql数据库多表联查

    内连接:查询的是多个表的交集 外连接:查询的是一张表的全部数据和另一张表满足要求的数据 student数据库表 grade数据库表 内连接: 隐式内连接 SELECT s.id, s. NAME, s ...

  2. Spring官网阅读(九)Spring中Bean的生命周期(上)

    文章目录 生命周期回调 1.Bean初始化回调 2.Bean销毁回调 3.配置默认的初始化及销毁方法 4.执行顺序 5.容器启动或停止回调 Lifecycle 接口 LifecycleProcesso ...

  3. webpack搭建环境步骤

    一.初始化 1.创建文件夹 2.npm init  -y 二.安装webpack 和webpack-cli 1.yarn add webpack webpack-cli@3.3.10 -D (这里指定 ...

  4. 【Spark】这一篇或许能让你大概了解如何通过JavaAPI实现DataFrame的相关操作

    文章目录 需求概述 步骤 一.创建Maven工程并导包 二.选用第一种方法:利用反射机制配合样例类构建DataFrame 开发代码 选用第二种方法:通过StrucType配合Row构建DataFram ...

  5. MATLAB与三大变换

    运行 Simulink 有三种方式: z 在 MATLAB 的命令窗口直接键入“Simulink”并回车: z 单击 MATLAB 工具条上的 Simulink 图标: z 在 MATLAB 菜单上选 ...

  6. 设计模式之GOF23观察者模式

    观察者模式Observer 广播机制 场景:多个观察者--被通知改变 CS的时候,人物移动坐标变化,更新每个人地图上的坐标 核心:当目标对象(Subject)的状态值改变时,需要及时告知所有观察者(O ...

  7. CentOS 7搭建Zookeeper和Kafka集群

    环境 CentOS 7.4 Zookeeper-3.6.1 Kafka_2.13-2.4.1 Kafka-manager-2.0.0.2 本次安装的软件全部在 /home/javateam 目录下. ...

  8. Python之sys.arg[]的用法解释

    转载自:https://www.cnblogs.com/liangmingshen/p/8906148.html sys.argv[]说白了就是一个从程序外部获取参数的桥梁,这个“外部”很关键,所以那 ...

  9. java 面向对象面试题,问答题,构造方法,抽象类,继承,多态,接口,异常总结;

    一,构造方法的特点 面向对象的思想是如何在java展现的呢? 就是通过类和对象 类是一组相关的属性和行为的集合.是一个抽象的概念. 对象是该类事物的具体表现形式.具体存在的个体. 一.抽象类的抽象方法 ...

  10. Python操作MongoDB代码示例

    import pymongo #pip install pymongo安装python操作mongodb的模块 myclient=pymongo.MongoClient(host='127.0.0.1 ...