实现 KMP 字符串匹配算法并支持通配符 ?

实现一个支持通配符  ? 的 KMP(Knuth-Morris-Pratt)字符串匹配算法需要对经典的 KMP 算法进行一些修改。在经典 KMP 算法中,我们构建一个部分匹配表(或称为前缀函数),用于在不匹配时决定模式串的移动步数。为了支持通配符  ?,我们需要在构建部分匹配表时考虑通配符的匹配特性。

算法步骤

  1. 构建部分匹配表(前缀函数)‌:

    • 在构建部分匹配表时,通配符  ? 可以匹配任意单个字符。
    • 因此,在计算前缀函数时,如果模式串的某个字符是  ?,它可以被视为与任意字符匹配。
  2. 进行字符串匹配‌:

    • 使用构建好的部分匹配表,在文本串中查找模式串。
    • 遇到通配符  ? 时,自动认为匹配成功。

实现代码

下面是一个 Python 实现,展示了如何修改 KMP 算法以支持通配符  ?

pythonCopy Codedef build_lps_with_wildcard(pattern):
    lps = [0] * len(pattern)
    length = 0  # Length of the previous longest prefix suffix
    i = 1
    while i < len(pattern):        if pattern[i] == pattern[length] or pattern[i] == '?' or pattern[length] == '?':
            length += 1
            lps[i] = length
            i += 1
        else:            if length != 0:
                length = lps[length - 1]            else:
                lps[i] = 0
                i += 1
    return lpsdef kmp_search_with_wildcard(text, pattern):
    lps = build_lps_with_wildcard(pattern)
    i = 0  # Index for text
    j = 0  # Index for pattern
    results = []    while i < len(text):        if pattern[j] == text[i] or pattern[j] == '?':
            i += 1
            j += 1
        if j == len(pattern):
            results.append(i - j)
            j = lps[j - 1]        elif i < len(text) and pattern[j] != text[i]:            if j != 0:
                j = lps[j - 1]            else:
                i += 1
    return results# 示例用法text = "ababcabcabababd"pattern = "ab?d"matches = kmp_search_with_wildcard(text, pattern)print("Pattern found at indices:", matches)

代码说明

  • build_lps_with_wildcard 函数‌:构建部分匹配表,考虑了通配符  ? 的匹配特性。
  • kmp_search_with_wildcard 函数‌:在文本串中查找模式串,使用部分匹配表来优化匹配过程。
  • 通配符处理‌:在比较字符时,如果模式串的字符是  ?,则自动认为匹配成功。

通过这种方式,我们可以在 KMP 算法中有效地支持通配符  ? 的匹配。


http://www.zgjzs.org

http://www.shangpin.org

http://www.snjrw.org

http://wangluo.zgjzs.org

http://zhineng.zgjzs.org

http://gaosu.zgjzs.org

http://anquan.zgjzs.org

http://wangzhan.zgjzs.org

http://jiaoyu.zgjzs.org

http://guanggao.zgjzs.org

http://shuju.zgjzs.org

http://zhifu.zgjzs.org

http://yingyong.zgjzs.org

http://yonghu.zgjzs.org

http://houtai.zgjzs.org

http://fenxi.zgjzs.org

http://jiekou.zgjzs.org

http://fenxiang.zgjzs.org

http://neirong.zgjzs.org

http://zhuce.zgjzs.org

http://tongji.zgjzs.org

http://ditu.zgjzs.org

http://tuisong.zgjzs.org

http://gouwu.zgjzs.org

http://tuiguang.zgjzs.org

http://shejiao.zgjzs.org

http://zhongguo.zgjzs.org

http://wangguan.zgjzs.org

http://yule.zgjzs.org

http://pingtai.zgjzs.org

http://jichu.zgjzs.org

http://wangjie.zgjzs.org

http://zhishi.zgjzs.org

http://shangcheng.zgjzs.org

http://dianzi.zgjzs.org

http://yinyue.zgjzs.org

http://tupian.zgjzs.org

http://shipin.zgjzs.org

http://wuliu.zgjzs.org

http://gongju.zgjzs.org

http://anquan.zgjzs.org

http://sousuo.zgjzs.org

http://mima.zgjzs.org

http://jiankong.zgjzs.org

http://ceshi.zgjzs.org

http://wangyou.zgjzs.org

http://zixun.zgjzs.org

http://chajian.zgjzs.org

http://kuaidi.zgjzs.org

http://liuliang.zgjzs.org

http://zhengce.zgjzs.org

http://peizhi.zgjzs.org

http://baocun.zgjzs.org

http://yonghu.shangpin.org

http://houtai.shangpin.org

http://pingtai.shangpin.org

http://wangzhan.shangpin.org

http://zhifu.shangpin.org

http://guanggao.shangpin.org

http://yinyue.shangpin.org

http://zixun.shangpin.org

http://shejiao.shangpin.org

http://tuisong.shangpin.org

http://wangguan.shangpin.org

http://zhineng.shangpin.org

http://wangluo.shangpin.org

http://anquan.shangpin.org

http://zhongguo.shangpin.org

http://shuju.shangpin.org

http://jiekou.shangpin.org

http://zhishi.shangpin.org

http://gongneng.shangpin.org

http://tongji.shangpin.org

http://shipin.shangpin.org

http://jiaoyu.shangpin.org

http://ditu.shangpin.org

http://dianzi.shangpin.org

http://mima.shangpin.org

http://liuliang.shangpin.org

http://gouwu.shangpin.org

http://zhengce.shangpin.org

http://yule.shangpin.org

http://baocun.shangpin.org

http://jichu.shangpin.org

http://fenxi.shangpin.org

http://fenxiang.shangpin.org

http://shangcheng.shangpin.org

http://kuaidi.shangpin.org

http://peizhi.shangpin.org

http://wuliu.shangpin.org

http://ceshi.shangpin.org

http://tupian.shangpin.org

http://wangyou.shangpin.org

http://chajian.shangpin.org

http://tuiguang.shangpin.org

http://yingyong.shangpin.org

http://zhuce.shangpin.org

http://sousuo.shangpin.org

http://jiankong.shangpin.org

http://neirong.shangpin.org

http://gongju.shangpin.org

http://zonghe.shangpin.org

http://zhifu.snjrw.org

http://houtai.snjrw.org

http://yule.snjrw.org

http://wangluo.snjrw.org

http://guanggao.snjrw.org

http://shuju.snjrw.org

http://pingtai.snjrw.org

http://ditu.snjrw.org

http://wangzhan.snjrw.org

http://shejiao.snjrw.org

http://jiekou.snjrw.org

http://zhishi.snjrw.org

http://zhineng.snjrw.org

http://jiaoyu.snjrw.org

http://zhongguo.snjrw.org

http://yinyue.snjrw.org

http://yonghu.snjrw.org

http://tuiguang.snjrw.org

http://gouwu.snjrw.org

http://baocun.snjrw.org

http://fenxiang.snjrw.org

http://fenxi.snjrw.org

http://gongneng.snjrw.org

http://wangguan.snjrw.org

http://zixun.snjrw.org

http://dianzi.snjrw.org

http://tupian.snjrw.org

http://wangyou.snjrw.org

http://chajian.snjrw.org

http://wuliu.snjrw.org

http://mima.snjrw.org

http://liuliang.snjrw.org

http://zhuce.snjrw.org

http://zhengce.snjrw.org

http://peizhi.snjrw.org

http://shipin.snjrw.org

http://jichu.snjrw.org

http://tongji.snjrw.org

http://kuaidi.snjrw.org

http://yingyong.snjrw.org

http://sousuo.snjrw.org

http://jiankong.snjrw.org

http://neirong.snjrw.org

http://gongju.snjrw.org

http://tuisong.snjrw.org

http://shangcheng.snjrw.org

http://anli.snjrw.org

http://dianhua.snjrw.org

http://fuwu.snjrw.org

请使用浏览器的分享功能分享到微信等