Sunday算法介绍及Java实现
前言
最初想写这篇文章的原因是在LeetCode上看到了一道实现strStr函数的题:
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
题目要求实现一个函数:
public int strStr(String haystack, String needle)
这个函数的两个参数名分别为haystack和needle,可能有人会疑惑为什么要用这么两个看着不相关的单词作为参数名,这里稍微解释下:英语有个口语叫"It’s a needle in a haystack",直接意思就是草垛寻针,也就是大海捞针之意。一方面传达了我们这个函数的功能,同时可能也想凸现一下这个操作的复杂度吧,老外有时候就是喜欢整一些黑色幽默。
因此,在后文的介绍里,haystack就是操作源数据,needle就是我们要去搜索的目标。
其实有很多算法可以来实现字符串查找,暴力的BF算法,经典的KMP算法,BM算法,Sunday算法等等,就效率和实现难度上来说,Sunday算法应该是性价比最高的,效率高,容易理解,实现也比较简单。
Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配。其核心思想是:在匹配过程中,模式串发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率。
下面我们通过示例来理解一下Sunday算法的工作原理:
示例原理
Sunday采用模式匹配的思想,匹配失败时,选择haystack中参加匹配的最末尾字符的后一位字符作为参照字符,如果该字符在needle串中有出现,则将needle串中最后出现该字符的位置与参照字符位置对齐继续比较,否则直接跳过该匹配区域,从参照字符的下一位重新开始比较。
OK,这一段实在太长,可能不太好理解,简单粗暴,来举个例子:
说明:
场景一:对照字符在needle中存在
首先从前往后对needle和haystack串中参与比较的子串here
进行字符比较,发现第一个字符匹配失败,则找到haystack参与比较的子串末尾字符的后一个字符e
作为参照字符,然后我们在needle串中从后往前找到字符e
,然后将两者位置对齐,如下图所示:
场景二:对照字符在needle中不存在
对齐后我们继续对比needle串和haystack中新参与比较的子串ere e
,发现依然不匹配。我们找到比较子串的后一个字符v
作为参照字符,寻找v在needle串中最后出现的位置,显然needle串中并不存在字符v
,这种情况下,我们可以直接将主串游标跳到字符v
后继续下一轮比较。
重新对齐后,比较发现依然不匹配,继续找到下一个对照字符h
,h在needle串中有出现,满足上述场景一的条件,则找到h
在needle串中最后出现的位置与参照字符对齐,继续比较,发现匹配成功。
代码实现
该算法的Java实现
public int Sunday(String haystack, String needle) {int hayLen = haystack.length();int nLen = needle.length();int i = 0;//haystack串的游标索引int j = 0;// needle串的游标索引// haystack剩余字符少于needle串时跳过比较while (i <= hayLen - nLen) {// 将needle串与haystack串中参与比较的子串进行逐个字符比对while (j < nLen && haystack.charAt(i + j) == needle.charAt(j)) {j++;}// 如果j等于needle串的长度说明此时匹配成功,可以直接返回此时主串的游标索引if (j == nLen) {return i;}// 不匹配时计算需要跳过的字符数,移动主串游标iif (i < hayLen - nLen) {// 对照字符在needle串存在,则需要跳过的字符数为从对照字符在needle串中最后出现的位置起剩余的字符个数// 不存在则跳过的字符数为needle串长度+1,也就是代码nLen-(-1)的情况i += (nLen - lastIndex(needle, haystack.charAt(i + nLen)));} else {return -1;}// 每次比较之后将needle游标置为0j=0;}return -1;}public int lastIndex(String str, char ch) {// 从后往前检索for (int j = str.length() - 1; j >= 0; j--) {if (str.charAt(j) == ch) {return j;}}return -1;}
实际环境中可以根据needle串的约束对needle串进行预处理,提前建立好索引,提高查找效率。
总结
通过上文介绍不难发现,Sunday算法在处理重复字符少的场景效率会很高,因为每次都可以跳过比较多的字符,很大程度的减少了比较次数,综合来说,Sunday算法的平均时间复杂度为O(n),最差情况的时间复杂度为O(n * m).
个人博客原文,转载请注明出处,如有错误的地方请留言给我更正,谢谢!
Sunday算法介绍及Java实现相关推荐
- sunday算法特征码_Sunday算法介绍及Java实现
前言 最初想写这篇文章的原因是在LeetCode上看到了一道实现strStr函数的题: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haysta ...
- apriori java_频繁模式挖掘apriori算法介绍及Java实现
频繁模式是频繁地出如今数据集中的模式(如项集.子序列或者子结构).比如.频繁地同一时候出如今交易数据集中的商品(如牛奶和面包)的集合是频繁项集. 一些基本概念 支持度:support(A=>B) ...
- BSO算法介绍及Java实现
头脑风暴过程 头脑风暴法经常被用来解决创新问题.它可以解决很多通常不能由一个人解决的难题.在头脑风暴过程中,一群背景不同的人聚集在一起进行讨论.引导者通常会参与这个过程,但不会直接参与想法的产生.引导 ...
- pca算法介绍及java实现_PCA算法原理及实现
众所周知,PCA(principal component analysis)是一种数据降维的方式,能够有效的将高维数据转换为低维数据,进而降低模型训练所需要的计算资源. 以上是比较官方的说法,下面是人 ...
- pca算法介绍及java实现_PCA实现教程
摘要: 手把手教你PCA降维技术!(有案例) 数据是机器学习模型的生命燃料.对于特定的问题,总有很多机器学习技术可供选择,但如果没有很多好的数据,问题将不能很好的解决.数据通常是大部分机器学习应用程序 ...
- mllib协同过滤 java实现_协同过滤(ALS)算法介绍及Spark MLlib调用实例(Scala/Java/Python)...
协同过滤 算法介绍: 协同过滤常被用于推荐系统.这类技术目标在于填充"用户-商品"联系矩阵中的缺失项.Spark.ml目前支持基于模型的协同过滤,其中用户和商品以少量的潜在因子来描 ...
- Sunday算法java实现
简介 Daniel M.Sunday于1990年提出的字符串模式匹配.其效率在匹配随机的字符串时比其他匹配算法还要更快,同时其实现方式比KMP,BM的实现容易太多. 算法原理 作为一个字符串模式匹配算 ...
- Java实现Sunday算法
Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配.其核心思想是:在匹配过程中,模式串发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率.相比于 ...
- 字符串匹配算法之Sunday算法
字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...
最新文章
- 【T07】不要低估tcp的性能
- .NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新
- 在服务器使用mysql_Linux服务器---使用mysql
- USE PDFCREATE TO CREATE A PDF FILE
- Python数据分析Numpy库方法简介(三)
- Shell中各种判断语法
- 工作208:element $message居中测试无法实现
- linux 14.04安装方法,Ubuntu 14.04 安装配置GNOME经典界面
- tomcat勾连mysql_tomcat9.0启动脚本startup.bat的分析
- 根据输入汉字获取其全拼及简拼
- 【牛客2021暑假多校10】Train Wreck(出栈顺序,建树,优先队列维护)
- 喜马拉雅音频下载工具 支持免费音频/VIP音频 文尾有彩蛋
- 修改mysql密码后wordpress_修改数据库密码后,wordpress网站打不开
- 云电脑服务:技术与商业模式双重创新
- PyQt5 组合键
- Hadoop详解(七)——Hive的原理和安装配置和UDF,flume的安装和配置以及简单使用,flume+hive+Hadoop进行日志处理
- 网箱补网水下机器人电控调试日志-驱动水下推进器-Day1
- DSPE-PEG-LTLRWVGLMS(二硬脂酰基磷脂酰乙醇胺-聚乙二醇-肿瘤靶向蛋白);神经胶质瘤归巢肽
- Odoo 16 企业版手册 - CRM (1)
- 流媒体协议(一):HLS 协议