Go使用Sunday算法实现PHP的strstr()

原文地址:Go使用Sunday算法实现PHP的strstr()

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

了解完定义后来看几个概念:

  1. 串:字符串的简称。

  2. 空串:长度为零的串。

  3. 主串:包含子串的串。

  4. 子串:串中任意个连续的字符组成的子序列。

  5. 模式串:子串的定位运算又称为串的模式匹配,是一种求子串第一个字符在主串中序号的运算,被匹配的主串称为目标串,子串称为模式串

来看题目:实现PHP的strstr()函数,给定haystack和needle两字符串,在haystack中找出needle第一次出现的位置(从0开始),如不存在,则返回-1。

运行效果示例一:输入:haystack = "hello", needle = "ll" 输出: 2

运行效果示例二:输入:haystack = "aaaaa", needle = "bba" 输出: -1

需要说明的是,当needle为空时,应返回0。

先来假设目标串为:Here is a little Hao,模式串为:little。

接下来将目标串和模式串对齐:

根据Sunday算法,首先从头部比较,如不匹配,则找到主串中位于模式串后面的第一个字符,也就是s,如下:

之后查看模式串中是否包含这个s,不包含则从s下一个字符开始比较,如下:

如仍不匹配,则重复上面的过程找到模式串下一个元素t,如下:

此时t被包含于模式串且t出现在模式串倒数第3的位置,此时将模式串前移3,如下:

成功了有木有?

整体看下在上述过程:

  1. 对齐模式串和目标串,从前向后匹配。

  2. 关注主串中位于模式串后第一个元素。

  3. 如关注的元素未在子串中出现则跳过。

  4. 出现则移动模式串,移动位数=子串长度-元素最右出现的位置(从0开始)。

实现代码如下:

package mainimport "fmt"func main() {
   
     fmt.Println(StrstrSunday("Here is a little Hao", "little"))}func StrstrSunday(haystack, needle string) int {
   
     // 验证字符串合法性  if len(haystack) < len(needle) {
   
       return -1  }  if haystack == needle || len(needle) == 0 {
   
       return 0  }  // index:最终位置的索引,needleIndex:目标匹配索引  index, i, needleIndex := -1, 0, 0  for i < len(haystack) {
   
       // 逐字节验证是否相等    if haystack[i] == needle[needleIndex] {
   
         // index为-1说明是首次匹配到的字符      if index == -1 {
   
           index = i      }      // 主串和模式串的索引+1      i++      needleIndex++      // 是否完成匹配验证      if needleIndex >= len(needle) {
   
           break      }      continue    }    // 走到此处说明未完成匹配,将匹配目标索引置为默认    index = -1    // 计算主串需要移动的位置    i = i + len(needle) - needleIndex    // 如主串索引大于主串实际长度表示未匹配成功,直接返回    if i >= len(haystack) {
   
         return index    }    // 计算下一字符在模式串中的位置    offset := 1    for j := len(needle) - 1; j > 0; j-- {
   
         if haystack[i] == needle[j] {
   
           offset = j        break      }    }    // 将主串索引左移指定长度,使当前字符和模式串最右匹配到的字符串对齐    i = i - offset    needleIndex = 0  }  return index}

至此,本次分享就结束了,后期会慢慢补充别的算法。

以上仅为个人观点,不一定准确,能帮到各位那是最好的。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

扫码关注公众号,获取更多优质内容。

  

おすすめ

転載: blog.csdn.net/luyaran/article/details/121135498