KY91 String Matching

KY91 String Matching

版本一:暴力解法

"版本一:暴力解法"

import sys
for line in sys.stdin:
    line = line.strip()
    text, pattern = line.split(" ")
    cnt = 0
    while(True):
        pos = text.find(pattern)
        if pos != -1:
            cnt += 1
            text = text[pos+1:]
        else:
            break
    print(cnt)

KMP算法:

import sys

def getNext(pattern):
    length = len(pattern)
    assert length > 0
    next = [None] * length
    for pointer in range(length):
        if pointer == 0:  # 第一个位置取值恒为-1
            next[pointer] = -1
            continue
        else:
            if pattern[pointer] ==  pattern[next[pointer-1]+1]:  # 利用前一个位置的前后缀匹配关系判断下一个字符是否继续得到匹配
                next[pointer] = next[pointer-1] + 1  # 下一个字符仍然匹配,因此长度加1
            else:
                if next[pointer-1] == -1:  # 表示截止到前一个字符,没有前后缀匹配,而且从上一个if语句得知当前字符也未匹配
                    next[pointer] = -1  # 未得到匹配,取值为-1
                    continue  # 继续下一次循环,计算next数组的下一个取值
                scan = next[next[pointer-1]]  # 当前匹配失败后,考虑前一个位置的前后缀匹配关系
                while(True):  
                    if pattern[scan+1] == pattern[pointer]:  # 得到匹配
                        next[pointer] = scan + 1  # 找到匹配的前后缀
                        break  # 跳出while循环
                    else:
                        if scan == -1:  # 表示整个字符串中都未得到匹配,因此取值为-1
                            next[pointer] = -1  # -1表示未得到匹配
                            break
                        else:
                            scan = next[scan]  # 匹配失败,继续前溯
    return next  # 返回next数组



# KMP函数接收一个文本字符串text和一个模式字符串pattern,实现KMP算法
def KMP(text,pattern):  # 返回在文本字符串text中匹配子串的起始位置,若不匹配则返回None
    next = getNext(pattern)  # 获取next数组,列表类型
    length_txt = len(text)  # 获得文本字符串的长度
    length_pat = len(pattern)  # 获得模式字符串的长度
    ptr_txt, ptr_pat = 0, 0  # 初始化两个字符串的指针位置,或者理解为索引位置
    count = 0
    while(ptr_txt<length_txt and ptr_pat<length_pat):  # 循环遍历整个文本字符串
        if pattern[ptr_pat] == text[ptr_txt]:  # 字符获得匹配
            ptr_txt += 1  # 文本字符串的指针加1 
            ptr_pat += 1  # 模式字符串的指针加1
            if ptr_pat == length_pat:  # 判断是否对模式字符串遍历完成
                count += 1
                ptr_txt, ptr_pat = ptr_txt-ptr_pat+1, 0
                # return (ptr_txt - ptr_pat)  # 获得匹配,返回匹配的起始位置
            continue  # 当前字符串成功匹配,继续进行下一次比较
        else:
            if ptr_pat == 0:  # 模式字符串前溯到起始位置,仍旧未获得匹配的前缀后缀,因此将文本字符串指针向后移动
                ptr_txt += 1  # 文本字符串的指正位置向后移动,继续扫描两个字符串进行比较
            else:
                ptr_pat = next[ptr_pat-1] + 1  # 匹配失败之后前溯
    print(count)  # 整个文本字符串中都未出现模式字符串,匹配失败,返回未匹配的标志None
            


for line in sys.stdin:
    text, pattern = line.strip().split(" ")
    KMP(text,pattern)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值