代码随想录训练营第III期--009--python

# 代码随想录训练营第III期--009--python
# 28 找出字符串中第一个匹配项的下标
def strStr(haystack: str, needle: str) -> int:
    lh = len(haystack)
    ln = len(needle)

    i,j = 0,0

    while i < lh and j < ln:
        if haystack[i] == needle[j]:
            i += 1
            j += 1
        else:
            i = i + 1 - j 
            j = 0 
    return i - j if j == ln else -1
# 459.重复的子字符串
# 学习KMP算法
a = 'aabaabaaf'
b = 'aabaaf'
# check if b has appeared in a
# 前缀表 what is 前缀表--最长相等前后缀
# b中b 的前缀
# a
# aa 
# kmp 算法的核心:求取最长相等的前后缀
# a       0
# aa      1
# aab     0
# aaba    1
# aabaa   2
# aabaaf  0
# kmp算法可以显著节约匹配复杂度从O(mxn)降低到O(m+n)
# 生成 next 数组
# next[j] 表示下标 j 之前的模式串 p 中,最长相等前后缀的长度
def generateNext(p: str):
    m = len(p)
    next = [0 for _ in range(m)]                # 初始化数组元素全部为 0
    
    left = 0                                    # left 表示前缀串开始所在的下标位置
    for right in range(1, m):                   # right 表示后缀串开始所在的下标位置
        while left > 0 and p[left] != p[right]: # 匹配不成功, left 进行回退, left == 0 时停止回退
            left = next[left - 1]               # left 进行回退操作
        if p[left] == p[right]:                 # 匹配成功,找到相同的前后缀,先让 left += 1,此时 left 为前缀长度
            left += 1
        next[right] = left                      # 记录前缀长度,更新 next[right], 结束本次循环, right += 1

    return next

# KMP 匹配算法,T 为文本串,p 为模式串
def kmp(T: str, p: str) -> int:
    n, m = len(T), len(p)
    
    next = generateNext(p)                      # 生成 next 数组
    
    j = 0                                       # j 为模式串中当前匹配的位置
    for i in range(n):                          # i 为文本串中当前匹配的位置
        while j > 0 and T[i] != p[j]:           # 如果模式串前缀匹配不成功, 将模式串进行回退, j == 0 时停止回退
            j = next[j - 1]
        if T[i] == p[j]:                        # 当前模式串前缀匹配成功,令 j += 1,继续匹配
            j += 1
        if j == m:                              # 当前模式串完全匹配成功,返回匹配开始位置
            return i - j + 1
    return -1                                   # 匹配失败,返回 -1
            

p = 'abab'
print(generateNext(p))
def repeat(s):
    if len(s) == 0:
        return False 
    nxt = generateNext(s)
    if nxt[-1] != 0 and len(s) % (len(s) - nxt[-1]) == 0:
        return True 
    return False
print(repeat(p))

# 1668. 最大重复子字符串

def maxRepeating(sequence: str, word: str) -> int:
    if sequence == word: return 1
    m_l = len(sequence) // len(word) + 1
    # 构建包含不同重复长度word的哈希表
    # tmp_d = collections.defaultdict(str)
    # for i in range(1, m_l):
    #     tmp_d[word*i] = i 
    # print(tmp_d.items())
    # for i in range(len(sequence)):
    #     for j in range(len(sequence) - 1, i, -1):
    #         if sequence[i:j] in tmp_d.keys():
    #             print(sequence)
    #             return tmp_d[sequence[i:j]]
    # return 0
    for i in range(m_l, -1, -1):
        if word * i in sequence:
            return i 
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

deyiwang89

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值