Sunday算法:查找字符串

Sunday算法是用于查找子串的一种算法,具体的应用场景看这里
相比于KMP,BM算法,Sunday算法更快,并且更好理解(自认为哈

下面用比较正式的语言介绍一下该算法:

原字符串为文本串,匹配的子串为模式串
从前往后匹配,在匹配失败时,关注的是文本串中参加匹配的最末位字符的下一位字符
—如果该字符没有在模式串中出现则直接跳过,即移动位数 = 匹配串长度 + 1;
—否则,其移动位数 = 模式串中最右端的该字符到末尾的距离+1。

是不是看的一脑袋问号?事实上在学习一个算法时,我认为不应该一开始就看概念,而是从例子入手。读懂了例子,就有事半功倍的效果。

话不多说,举一个栗子:
令文本串为:"substring searching algorithm
令模式串为:search

.

1.初始状态:

在这里插入图片描述
现在匹配失败了,那么我们要试图移动模式串,再进行下一次匹配
(事实上我觉得各个算法不同的地方就在于怎么移动模式串)

Sunday算法选择关注文本串中参加匹配的最末位字符的下一位字符

在这里插入图片描述
在这里,就是箭头指向的 i 。可以看到,i 没有出现在模式串search中。
所以,我们可以说,文本串中所有包括i的部分,都不会与search匹配。

2.移动模式串

这样我们可以直接将search直接移动到 i 的后面。从i后面的元素n开始匹配。
在这里插入图片描述
ok,现在模式串search还是没有与文本串匹配。我们继续关注上文所说的“下一位字符”,也就是箭头所指的 r。
r出现在了模式串中,出现在模式串的倒数第3位。
那么我们将模式串向右移动3位。也就是将两个r先匹配起来.

3.移动模式串

在这里插入图片描述
这里,匹配成功了。完结撒花~~

现在,回头看看该算法的定义,会不会豁然开朗了呢?
接下来就上代码了~

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:

        def calShiftMat(st):
            dic = {}
            for i in range(len(st)-1,-1,-1):
                if not dic.get(st[i]):
                    dic[st[i]] = len(st)-i
            dic["ot"] = len(st)+1
            return dic
        # 关于这个函数,我觉得就是为了降低时间复杂度的
        # 之前我是用in和index来判断“下一位字符”以及移动的距离。
        # 但leetcode过不了..

        if not needle:
            return 0
        len_a = len(haystack)
        len_b = len(needle)
        dic = calShiftMat(needle)
        start = 0
        while start <= len_a - len_b:
            if haystack[start:start+len_b] == needle:
                return start           # 如果匹配,直接返回起始位置
            else :
                if  start+len_b >= len_a:
                    return -1
                cur_c = haystack[start+len(needle)]
                if dic.get(cur_c):
                    start += dic[cur_c]
                else:
                    start += dic["ot"]
        return -1 if start+len(needle) >= len(haystack) else start

.

参考资料

  1. https://blog.csdn.net/v_july_v/article/details/7041827#
  2. https://leetcode-cn.com/problems/implement-strstr/solution/python3-sundayjie-fa-9996-by-tes/
发布了19 篇原创文章 · 获赞 1 · 访问量 784

猜你喜欢

转载自blog.csdn.net/weixin_43901558/article/details/104680352