字符串匹配的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 提供了一种直接的、透明的方式来调用服务器上的方法和处理服务器响应,而无需编写大量的手动…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...