模式匹配的朴素算法与KMP算法及代码实现

模式匹配的朴素算法是在匹配过程中,将模式串一位一位地往后移动。而更高效的KMP算法是在匹配过程中出现字符不相等时,模式串利用已经得到的“部分匹配表”结果将模式串向右滑动若干位,重新开始下一趟的匹配,例如对于主串“acabaabaabcac”,模式串“abaabcac”,利用KMP算法进行匹配的过程是:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
KMP算法工具
"""

class KPM_Matcher():
    def __init__(self):
        self.__measured_array = None
        self.__target_array = None

    def kmp_match(self, measured_array, target_array):
        """
        kmp算法
        :param measured_array:
        :param target_array:
        :return:
        """
        self.__measured_array = len(measured_array)
        self.__target_array = len(target_array)
        table = self.partial_table(target_array)
        cur = 0    #移动指针
        while cur <= self.__measured_array - self.__target_array:
            for i in range(self.__target_array):
                if measured_array[i + cur] != target_array[i]:
                    cur += max(i - table[i-1], 1)
                    break
            else:
                return True
        return False

    def partial_table(self, target_array):
        """
        部分匹配表
        :param target_array:
        :return:
        """
        prefix = set()
        postfix = set()
        ret = [0]
        for i in range(1, self.__target_array):
            prefix.add(target_array[:i])
            # print("pre:{}".format(prefix))
            postfix = {target_array[j:i+1] for j in range(1, i+1)}
            # print("post:{}".format(postfix))
            ret.append(len((prefix & postfix or {''}).pop()))
            # print(ret)
        return ret

    def naive_match(self, measured_array, target_array):
        """
        朴素匹配算法,将字符串一位一位地往后移动进行匹配
        :param measured_array:
        :param target_array:
        :return:
        """
        self.__measured_array = len(measured_array)
        self.__target_array = len(target_array)
        for i in range(self.__measured_array - self.__target_array + 1):
            if measured_array[i:i + self.__target_array] == target_array:
                return True
        return False


if __name__ == "__main__":
    kmp = KPM_Matcher()
    print(kmp.kmp_match("123456789","4545"))
    print(kmp.naive_match("123456789","123"))

  

转载于:https://www.cnblogs.com/liangzp/p/8706900.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值