数组中搜索子数组算法

'''
已经完美搞定, 通过return_all参数来控制是否需要找全!

'''

def kmp(mom_string, son_string,return_all=False):
    # 传入一个母串和一个子串
    # 返回子串匹配上的第一个位置,若没有匹配上返回-1
    # 首先是合法性检验!!!!!!!!!!!!!!!!!!!!!!!
    test = []
    if type(mom_string) != type(test) or type(son_string) != type(test):
        return -1
    if len(son_string) == 0:
        return 0
    if len(mom_string) == 0:
        return -1





    # 针对sonstring计算next数组.
    # 求next数组
    next = [-1] * len(son_string)
    if len(son_string) > 1:  # 这里加if是怕列表越界
        next[1] = 0
        i, j = 1, 0
        while i < len(son_string) - 1:  # 这里一定要-1,不然会像例子中出现next[8]会越界的
            if j == -1 or son_string[i] == son_string[j]: # 如果next数组匹配到了
                i += 1
                j += 1
                next[i] = j
            else:
                j = next[j]
    if not return_all: # 下面这段是返回第一个符合的index的逻辑代码.
        # kmp框架
        m = s = 0  # 母指针和子指针初始化为0
        while (s < len(son_string) and m < len(mom_string)):
            # 匹配成功,或者遍历完母串匹配失败退出
            if s == -1 or mom_string[m] == son_string[s]: # 表示当前2个指针对应字符相通,匹配陈宫.所以都向后便宜一个.
                m += 1
                s += 1
            else:
                s = next[s]

        if s == len(son_string):  # 匹配成功
            return m - s
    else:
        # kmp框架
        save=[]
        m = s = 0  # 母指针和子指针初始化为0
        while m < len(mom_string):
            # 匹配成功,或者遍历完母串匹配失败退出
            if s == len(son_string):  # 匹配成功
                save.append(m - s)
                s=0
            if s == -1 or mom_string[m] == son_string[s]: # 表示当前2个指针对应字符相通,匹配陈宫.所以都向后便宜一个.
                m += 1
                s += 1

            else:
                s = next[s]
        if s == len(son_string):  # 用来匹配最末未的一个陪陪成功的时候.
            save.append(m - s)
        return save


    # 匹配失败
    return -1


# 测试
mom_string = [3,4,1,3,4,5,3,5,4,3,4,3,4,6,7,3,4]
son_string = [3,4]
print(kmp(mom_string, son_string))
print(kmp(mom_string, son_string,return_all=True))
View Code

 

 

posted on 2020-07-27 12:45  张博的博客  阅读(307)  评论(0编辑  收藏  举报

导航