实现一个支持通配符
? 的 KMP(Knuth-Morris-Pratt)字符串匹配算法需要对经典的 KMP 算法进行一些修改。在经典 KMP 算法中,我们构建一个部分匹配表(或称为前缀函数),用于在不匹配时决定模式串的移动步数。为了支持通配符
?,我们需要在构建部分匹配表时考虑通配符的匹配特性。
算法步骤
-
构建部分匹配表(前缀函数):
- 在构建部分匹配表时,通配符
?可以匹配任意单个字符。 - 因此,在计算前缀函数时,如果模式串的某个字符是
?,它可以被视为与任意字符匹配。
- 在构建部分匹配表时,通配符
-
进行字符串匹配:
- 使用构建好的部分匹配表,在文本串中查找模式串。
- 遇到通配符
?时,自动认为匹配成功。
实现代码
下面是一个 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