前言

最初想写这篇文章的原因是在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实现相关推荐

  1. sunday算法特征码_Sunday算法介绍及Java实现

    前言 最初想写这篇文章的原因是在LeetCode上看到了一道实现strStr函数的题: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haysta ...

  2. apriori java_频繁模式挖掘apriori算法介绍及Java实现

    频繁模式是频繁地出如今数据集中的模式(如项集.子序列或者子结构).比如.频繁地同一时候出如今交易数据集中的商品(如牛奶和面包)的集合是频繁项集. 一些基本概念 支持度:support(A=>B) ...

  3. BSO算法介绍及Java实现

    头脑风暴过程 头脑风暴法经常被用来解决创新问题.它可以解决很多通常不能由一个人解决的难题.在头脑风暴过程中,一群背景不同的人聚集在一起进行讨论.引导者通常会参与这个过程,但不会直接参与想法的产生.引导 ...

  4. pca算法介绍及java实现_PCA算法原理及实现

    众所周知,PCA(principal component analysis)是一种数据降维的方式,能够有效的将高维数据转换为低维数据,进而降低模型训练所需要的计算资源. 以上是比较官方的说法,下面是人 ...

  5. pca算法介绍及java实现_PCA实现教程

    摘要: 手把手教你PCA降维技术!(有案例) 数据是机器学习模型的生命燃料.对于特定的问题,总有很多机器学习技术可供选择,但如果没有很多好的数据,问题将不能很好的解决.数据通常是大部分机器学习应用程序 ...

  6. mllib协同过滤 java实现_协同过滤(ALS)算法介绍及Spark MLlib调用实例(Scala/Java/Python)...

    协同过滤 算法介绍: 协同过滤常被用于推荐系统.这类技术目标在于填充"用户-商品"联系矩阵中的缺失项.Spark.ml目前支持基于模型的协同过滤,其中用户和商品以少量的潜在因子来描 ...

  7. Sunday算法java实现

    简介 Daniel M.Sunday于1990年提出的字符串模式匹配.其效率在匹配随机的字符串时比其他匹配算法还要更快,同时其实现方式比KMP,BM的实现容易太多. 算法原理 作为一个字符串模式匹配算 ...

  8. Java实现Sunday算法

    Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配.其核心思想是:在匹配过程中,模式串发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率.相比于 ...

  9. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

最新文章

  1. 【T07】不要低估tcp的性能
  2. .NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新
  3. 在服务器使用mysql_Linux服务器---使用mysql
  4. USE PDFCREATE TO CREATE A PDF FILE
  5. Python数据分析Numpy库方法简介(三)
  6. Shell中各种判断语法
  7. 工作208:element $message居中测试无法实现
  8. linux 14.04安装方法,Ubuntu 14.04 安装配置GNOME经典界面
  9. tomcat勾连mysql_tomcat9.0启动脚本startup.bat的分析
  10. 根据输入汉字获取其全拼及简拼
  11. 【牛客2021暑假多校10】Train Wreck(出栈顺序,建树,优先队列维护)
  12. 喜马拉雅音频下载工具 支持免费音频/VIP音频 文尾有彩蛋
  13. 修改mysql密码后wordpress_修改数据库密码后,wordpress网站打不开
  14. 云电脑服务:技术与商业模式双重创新
  15. PyQt5 组合键
  16. Hadoop详解(七)——Hive的原理和安装配置和UDF,flume的安装和配置以及简单使用,flume+hive+Hadoop进行日志处理
  17. 网箱补网水下机器人电控调试日志-驱动水下推进器-Day1
  18. DSPE-PEG-LTLRWVGLMS(二硬脂酰基磷脂酰乙醇胺-聚乙二醇-肿瘤靶向蛋白);神经胶质瘤归巢肽
  19. Odoo 16 企业版手册 - CRM (1)
  20. 流媒体协议(一):HLS 协议

热门文章

  1. 图书信息管理系统c/c++
  2. 国产巨芯:中芯国际燃爆芯片圈;360守护国产UOS系统安全
  3. 总结 : 十分钟快速理解Java容器
  4. html5 article 炫酷,Html5新标签之article标签详解
  5. 巡检机器人的实施步骤
  6. ctkPlugin插件系统实现项目插件式开发
  7. VS2015无法打开输入文件xxx.lib
  8. c语言如果输出宽度大于,C语言格式输出
  9. u3d:后期屏幕渲染特效
  10. 一元三次方程求解-二分