首页 > 其他分享 >KMP 学习笔记与总结

KMP 学习笔记与总结

时间:2023-07-11 12:12:09浏览次数:36  
标签:总结 题目 int s2 s1 ne 笔记 KMP

KMP 学习笔记与总结

目录

KMP

信息学奥赛一本通

img
img
img

模板

AcWing

// 下标从1开始
// s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
求模式串的Next数组:
for (int i = 2, j = 0; i <= m; i ++ )
{
    while (j && p[i] != p[j + 1]) j = ne[j];
    if (p[i] == p[j + 1]) j ++ ;
    ne[i] = j;
}

// 匹配
for (int i = 1, j = 0; i <= n; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == m)
    {
        j = ne[j]; // j = 0;
        // 匹配成功后的逻辑
    }
}

注意:16行的 j = ne[j]可重叠的情况。
如果换成 j = ne[j]不可重叠的情况。

自己的

// 下标从1开始
void init() {
	for (int i = 1, j = 0; i <= n; i ++ ) {
		while (j && p[i + 1] != p[j + 1]) j = ne[j];
		if (p[i + 1] == p[j + 1]) j ++ ;
		ne[i + 1] = j;
	}
}
void Solve() {
	for (int i = 0, j = 0; i <= m; i ++ ) {
		while (j && s[i + 1] != p[j + 1]) j = ne[j];
		if (s[i + 1] == p[j + 1]) j ++ ;
		if (j == n) {
			cout << i + 1 - n << " "; // 匹配成功后的逻辑
			j = ne[j]; // j = 0;
		}
	}
}

注意:14行的 j = ne[j]可重叠的情况。
如果换成 j = ne[j]不可重叠的情况。

题目

题目1

模板题 - 可重叠 - luogu P3375 【模板】KMP 字符串匹配   

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m; // n主串长度 
char s1[N], s2[N]; // s1主串 
int ne[N];
int main() {
	cin >> s1 + 1 >> s2 + 1;
	n = strlen(s1 + 1), m = strlen(s2 + 1);
	for (int i = 1, j = 0; i <= m; i ++ ) {
		while (j && s2[i + 1] != s2[j + 1]) j = ne[j];
		if (s2[i + 1] == s2[j + 1]) j ++ ;
		ne[i + 1] = j;
	} 
	for (int i = 0, j = 0; i <= n; i ++ ) {
		while (j && s1[i + 1] != s2[j + 1]) j = ne[j];
		if (s1[i + 1] == s2[j + 1]) j ++ ;
		if (j == m) {
			cout << i + 1 - m + 1 << endl;
			j = ne[j];
		}
	}
	for (int i = 1; i <= m; i ++ )
		cout << ne[i] << " ";
	return 0;
}

题目2

其他题目 - 不可重叠 - LibreOJ #10043. 「一本通 2.2 例 1」剪花布条

题目可以转化为给定字符串 s1s2,求申 s1 中可以分割出多少个互不重叠的串 s2
直接用 KMP 算法即可,注意计算不重叠的匹配个数。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
char s1[N], s2[N]; // s1 是主串 
int ne[N], ans;
int main() {
	while (true) {
		cin >> s1 + 1;
		n = strlen(s1 + 1);
		if (s1[1] == '#' && n == 1) break;
		cin >> s2 + 1;
		m = strlen(s2 + 1); 
		// 初始化 ne 数组 
		for (int i = 1, j = 0; i <= m; i ++ ) {
			while (j && s2[i + 1] != s2[j + 1]) j = ne[j];
			if (s2[i + 1] == s2[j + 1]) j ++ ;
			ne[i + 1] = j;
		}
		// 匹配过程 
		ans = 0;
		for (int i = 0, j = 0; i <= n; i ++ ) {
			while (j && s1[i + 1] != s2[j + 1]) j = ne[j];
			if (s1[i + 1] == s2[j + 1]) j ++ ;
			if (j == m) {
				ans ++ ;
				j = 0; // 从头开始重新匹配,保证不重叠 
			}
		}
		cout << ans << endl; 
	} 
	return 0;
}

标签:总结,题目,int,s2,s1,ne,笔记,KMP
From: https://www.cnblogs.com/MingruiYang/p/17544174.html

相关文章

  • xss漏洞总结
    Xss漏洞(跨站脚本攻击)原理通过网页插入恶意脚本,如前端的HTML和JavaScript。当用户浏览网页时,浏览器执行用户输入的JS代码,实现控制用户浏览器危害获取用户的cookie,利用cookie盗取用户对该网站的操作权限;获取用户联系人列表,利用被攻击者的身份向特定的目标群发送垃圾信息XSS的......
  • 永磁同步电机矢量控制C代码,全部从项目中总结得到,采用的S- 永磁同步电机矢量控制C代码,
    永磁同步电机矢量控制C代码,全部从项目中总结得到,采用的S-永磁同步电机矢量控制C代码,全部从项目中总结得到,采用的S-function模式仿真,与实际项目运行基本一致,可以直接复制代码移植到工程实践项目中去。ID:22390662457992412......
  • 线段树 算法笔记
    已知一个长度为\(n\)的序列\(a\),共有\(m\)次操作,每次操作如下:将某区间每一个数加上\(k\)。求出某区间每一个数的和。Luogu-P3372【模板】线段树1之前学过一个算法叫做树状数组,它的本质就是将一个\([1,x]\)的区间二进制拆分装化成若干个区间,数组里的每一个元素......
  • (转)Docker格式化输出命令:"docker inspect --format" 学习笔记
    原文:https://www.cnblogs.com/kevingrace/p/6424476.htmlDocker--format参数提供了基于Go模板的日志格式化输出辅助功能,并提供了一些内置的增强函数。什么是模板?上图是大家熟悉的 MVC框架(ModelViewController): Model(模型,通常在服务端)用于处理数据、View(视图,客户端代码......
  • web前端 第四天总结
    案例1:盒子模型<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</ti......
  • Java语言基础知识全总结
    一.Java的优点1.      跨平台性。一次编译,到处运行。Java编译器会将Java代码编译成能在JVM上直接运行的字节码文件,C++会将源代码编译成可执行的二进制代码文件,所以C++执行速度快2.      纯面向对象。Java所有的代码都必须在类中书写。C++兼具面向对象和面向过程的特......
  • Unity3D高级编程主程手记 学习笔记五:网络通讯
    1.C#实现TCP1.1实现所需APIC#提供了TCP的Socket连接API。一般的游戏项目我们不会使用阻塞方式连接和接收。因为我们不会让游戏卡住等待传输链接,大多数情况下我们还是会使用更加平滑的异步操作作为网络连接和收发的操作。常用的API如下:BeginConnect:开始连接Be......
  • Golang学习笔记-常量
    声明常量声明常量关键字:constconst{常量名}{常量类型}或const{常量名}={常量值}预定义常量预定义常量:true,false,iota其中true,false是布尔类型,iota是一个自增常量,从0开始取值它每出现一次,它自身的值会加1iota用法const{ money0=iota//值为0......
  • Golang学习笔记-变量
    声明变量声明变量关键字varvar{变量名称}{变量类型}例子//声明一个变量为v1的整型变量,未赋值时默认值为0varv1int//声明一个变量为v2的浮点型变量,未赋值时默认值为0varv2float32//声明一个变量为v3的数组变量(数组中的元素为整型),未赋值时默认值为nilvarv3......
  • 矩阵优化学习笔记
    前言矩阵优化是一种比较靠思维的优化算法,一般简单题考的比较少。个人认为矩阵优化中在运用,所以放了几道题目来讲解。定义矩阵一个\(m\timesn\)的矩阵是一个由\(m\)行\(n\)列元素排列成的矩形阵列。大概长成下面这个样子的。\[A=\underbrace{\begin{bmatrix}a_{1,1......