字符串匹配的Rabin–Karp算法
leetcode-28 实现strStr()
更熟悉的字符串匹配算法可能是KMP算法, 但在Golang中,使用的是Rabin–Karp算法
一般中文译作 拉宾-卡普算法,由迈克尔·拉宾与理查德·卡普于1987年提出
“要在一段文本中找出单个模式串的一个匹配,此算法具有线性时间的平均复杂度,其运行时间与待匹配文本和模式串的长度成线性关系。虽然平均情况下,此算法表现优异,但最坏情况下,其复杂度为文本长与模式串长的乘积
尽可能多的利用上一步的结果,这是优化时间复杂度的一大核心
对于数字类型的字符串,可有如下匹配方法:
将该方法扩展到非数字类型的字符串:
$$\begin{gather}
对于长度为n的字符串 x_{0} x_{1} x_{2} ... x_{n-1},\\其对应的“值”val为\\
val = x_{0} \times r^{n-1} + x_{1}\times r^{n-2} + ... + x_{n-1}\times r^{0}
\\其中r为进制数\end{gather}$
ASCII:英语字符与二进制位之间的关系 (其他语言??)
Unicode:将世界上所有的符号都纳入其中, 每个符号都对应一个独一无二的编码,最多可以容纳1114112个字符(2021年9月公布的14.0.0,已经收录超过14万个字符) (有个问题是浪费空间。。) 也译作统一码/万国码/国际码
UTF-8: 使用最广的一种 Unicode 的实现方式 (最大特点是 变长的编码方式)
字符编码笔记:ASCII,Unicode 和 UTF-8
中日韩汉字Unicode编码表
源码注释:
将源码中的16777619进制改为10进制,从字符串31415926中搜索4159:
4159
package main
import (
"fmt"
"strconv"
)
func main() {
var primeRK uint32 = 10
sep := "4159"
hash := uint32(0)
for i := 0; i < len(sep); i++ {
//fmt.Println(sep[i])
//fmt.Println(string(sep[i]))
next, _ := strconv.Atoi(string(sep[i]))
//hash = hash*primeRK + uint32(sep[i])
hash = hash*primeRK + uint32(next)
fmt.Println(hash)
}
}
输出为:
4
41
415
4159
完整的以10为primeRK,从31415926中搜索4159的代码:
package main
import (
"fmt"
"strconv"
)
const PrimeRKNew = 10
func main() {
str := `31415926`
substr := "4159"
fmt.Println("最终结果为:", IndexRabinKarpNew(str, substr))
}
func HashStrNew(sep string) (uint32, uint32) {
hash := uint32(0)
for i := 0; i < len(sep); i++ {
//fmt.Println(sep[i])
//fmt.Println(string(sep[i]))
next, _ := strconv.Atoi(string(sep[i]))
//hash = hash*primeRK + uint32(sep[i])
hash = hash*PrimeRKNew + uint32(next)
fmt.Println(hash)
}
var pow, sq uint32 = 1, PrimeRKNew
for i := len(sep); i > 0; i >>= 1 {
fmt.Println("i is:", i, "---", "i&1 is:", i&1)
if i&1 != 0 {
pow *= sq
}
sq *= sq
fmt.Println("pow is:", pow)
}
return hash, pow
}
func IndexRabinKarpNew(s, substr string) int {
// Rabin-Karp search
hashss, pow := HashStrNew(substr)
fmt.Println("hashss, pow:", hashss, pow)
fmt.Println("~~~分割线~~~")
n := len(substr)
var h uint32
for i := 0; i < n; i++ {
next1, _ := strconv.Atoi(string(s[i]))
//h = h*PrimeRKNew + uint32(s[i])
fmt.Println("next1 is:", next1)
h = h*PrimeRKNew + uint32(next1)
}
fmt.Println("h即T串初始值为:", h)
if h == hashss && s[:n] == substr {
return 0
}
for i := n; i < len(s); {
h *= PrimeRKNew
fmt.Println("h*=:", h)
last, _ := strconv.Atoi(string(s[i])) //当前T串的最后一个元素
fmt.Println("last is:", last)
//h += uint32(s[i])
h += uint32(last)
fmt.Println("h+=:", h)
//h -= pow * uint32(s[i-n])
first, _ := strconv.Atoi(string(s[i-n])) //当前T串的第一个元素
fmt.Println("first is:", first)
h -= pow * uint32(first)
fmt.Println("h-=:", h)
i++
fmt.Println("---下次循环的 i为 ---", i)
if h == hashss && s[i-n:i] == substr { //s[i-n:i]为当前的T串
return i - n
}
}
return -1
}
输出为:
4
41
415
4159
i is: 4 --- i&1 is: 0
pow is: 1
i is: 2 --- i&1 is: 0
pow is: 1
i is: 1 --- i&1 is: 1
pow is: 10000
hashss, pow: 4159 10000
~~~分割线~~~
next1 is: 3
next1 is: 1
next1 is: 4
next1 is: 1
h即T串初始值为: 3141
h*=: 31410
last is: 5
h+=: 31415
first is: 3
h-=: 1415
---下次循环的 i为 --- 5
h*=: 14150
last is: 9
h+=: 14159
first is: 1
h-=: 4159
---下次循环的 i为 --- 6
最终结果为: 2
strings.Contains()源码阅读暨internal/bytealg初探
书籍推荐
柔性字符串匹配
牛刀小试:
力扣28. 实现strStr()
力扣187. 重复的DNA序列
力扣686. 重复叠加字符串匹配
另:
除去KMP和RK算法,字符串匹配还有 Boyer-Moore算法(简称BM算法)系列算法,其核心思想是:
“在字符串匹配过程中,模式串发现不匹配时,跳过尽可能多的字符以进行下一步的匹配,从而提高匹配效率
BM算法的简化版Horspool算法
以及性能更好的Sunday算法
Python用的也不是KMP,而是boyer-moore和horspool, 源码点此
KMP 算法的实际应用有哪些?
图解字符串匹配之Horspool算法和Boyer-Moore算法
本文由 mdnice 多平台发布
相关文章:
字符串匹配的Rabin–Karp算法
leetcode-28 实现strStr() 更熟悉的字符串匹配算法可能是KMP算法, 但在Golang中,使用的是Rabin–Karp算法 一般中文译作 拉宾-卡普算法,由迈克尔拉宾与理查德卡普于1987年提出 “ 要在一段文本中找出单个模式串的一个匹配,此算法具有线性时间的平均复杂度࿰…...
傅里叶变换(FFT)笔记存档
参考博客:https://www.luogu.com.cn/blog/command-block/fft-xue-xi-bi-ji 目录: FFT引入复数相关知识单位根及其相关性质DFT过程(难点)DFT结论(重要)IDFT结论(重要)IDFT结论证明&…...
ELK安装、部署、调试 (二) ES的安装部署
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口操作ES,也可以利用Java API。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业…...
Android 13 - Media框架(8)- MediaExtractor
上一篇我们了解了 GenericSource 需要依赖 IMediaExtractor 完成 demux 工作,这一篇我们就来学习 android media 框架中的第二个服务 media.extractor,看看 IMediaExtractor 是如何创建与工作的。 1、MediaExtractorService media.extractor 和 media.p…...
Flutter 混合开发调试
针对Flutter开发的同学来说,大部分的应用还是Native Flutter的混合开发,所以每次改完Flutter代码,运行整个项目无疑是很费时间的。所以Flutter官方也给我们提供了混合调试的方案【在混合开发模式下进行调试】,这里以Android Stud…...
C语言每日一练------(Day3)
本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今天练习题的关键字: 尼科彻斯定理 等差数列 💓博主csdn个人主页:…...
14、监测数据采集物联网应用开发步骤(10)
监测数据采集物联网应用开发步骤(9.2) Modbus rtu协议开发 本章节在《监测数据采集物联网应用开发步骤(7)》基础上实现可参考《...开发步骤(7)》调试工具,本章节代码需要调用modbus_tk组件,阅读本章节前建议baidu熟悉modbus rtu协议内容 组件安装modb…...
Linux禅道上修改Apache 和 MySQL 默认端口号
1. 修改Apache默认端口号 80 cd /opt/zbox/etc/apachevim httpd.conf :wq 保存 2. 修改MySQL默认端口号 3306 cd /opt/zbox/etc/mysql vim my.cnf :wq 保存 3. 重启服务 ./zbox restart...
操作教程|通过1Panel开源Linux面板快速安装DataEase
DataEase开源数据可视化分析工具(dataease.io)的在线安装是通过在服务器命令行执行Linux命令来进行的。但是在实际的安装部署过程中,很多数据分析师或者业务人员经常会因为不熟悉Linux操作系统及命令行操作方式,在安装DataEase的过…...
机器学习策略——优化深度学习系统
正交化(Orthogonalization) 老式电视机,有很多旋钮可以用来调整图像的各种性质,对于这些旧式电视,可能有一个旋钮用来调图像垂直方向的高度,另外有一个旋钮用来调图像宽度,也许还有一个旋钮用来…...
ES6中Proxy和Proxy实例
1.Proxy Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器” 使用方法 let p new Proxy(target, handler);其中,target 为被代理对象。handler 是一个对象,其声明了代理 target 的一些操作。p 是…...
UDP协议的重要知识点
UDP,即用户数据报协议(User Datagram Protocol),是一个简单的无连接的传输层协议。与TCP相比,UDP提供了更少的错误检查机制,并允许数据包在网络上更快地传输。在这篇博客中,我们将深入探讨UDP的…...
QT6为工程添加资源文件,并在ui界面引用
以添加图片资源为例 右键工程名字(不是最上面的名字),点击添加现有文件 这种方式虽然添加到了工程中,但不能在UI设计界面完成引用。主要原因可能是未把文件放入到项目资源文件中,以下面一种方式可以看出区别。 点击添…...
Python小知识 - 如何使用Python的Flask框架快速开发Web应用
如何使用Python的Flask框架快速开发Web应用 现在越来越多的人把Python作为自己的第一语言来学习,Python的简洁易学的语法以及丰富的第三方库让人们越来越喜欢上了这门语言。本文将介绍如何使用Python的Flask框架快速开发Web应用。 Flask是一个使用Python编写的轻量级…...
Flutter 项目结构文件
1、Flutter项目的文件结构 先helloworld项目,看看它都包含哪些组成部分。首先,来看一下项目的文件结构,如下图所示。 2、介绍上图的内容。 -litb/main.dart文件:整个应用的入口文件,其中的main函数是整个Flutter应…...
未找到System.Runtime.InteropServices.Marshal.GetTypeFromCLSID(System.Guid) 方法错误
记录此问题实际上是由于.netFrame框架配置太高引起的,一般常见于二次开发中,因为二次开发一般都是引用的com组件,在引用过程中后台代码调用了 Method not found: System.Type System.Runtime.InteropServices.Marshal.GetTypeFromCLSID(Syste…...
人员位置管理,点亮矿山安全之路
矿山作为一个高危行业,安全问题一直备受关注。人员定位置管理是现代矿山安全管理的重要一环,可以帮助企业更好地实现对人员的实时监控和管理。因此,矿山人员位置管理系统对于矿山安全生产和管理非常重要,可以帮助减少安全事故的发…...
node-red - 读写操作redis
node-red - 读写操作redis 一、前期准备二、node-red安装redis节点三、node-red操作使用redis节点3.1 redis-out节点 - 存储数据到redis3.2 redis-cmd节点 - 存储redis数据3.3 redis-in节点 - 查询redis数据 附录附录1:redis -out节点示例代码附录2:redi…...
【图像处理】模板匹配的学习笔记
OpenCV的模板匹配算法 cv.TM_CCOEFFcv.TM_CCOEFF_NORMEDcv.TM_CCORRcv.TM_CCORR_NORMEDcv.TM_SQDIFFcv.TM_SQDIFF_NORMED 匹配代码模板 image cv2.imread(r"scene.png", cv2.IMREAD_GRAYSCALE) template cv2.imread(r"element.png", cv2.IMREAD_GRAYSC…...
Ext JS之Ext Direct快速入门
Ext Direct是一个专有名词, Direct是直接的意思。 Ext Direct 是 Ext JS 框架中的一个功能模块,用于简化前端 JavaScript 应用程序与后端服务器之间的通信和数据交换。 Ext Direct 提供了一种直接的、透明的方式来调用服务器上的方法和处理服务器响应,而无需编写大量的手动…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
