多模式串匹配的 3 种方法

例题: Another Substring Query Problem

由于次题中模式串有重复,会影响时间复杂度,所以我们要提前处理相同的字符串。下面的方法均假设无重复模式串。并以nn为模式串的总长度,mm为文本串的长度。

方法一:字符串哈希

由于总长为nn的模式串最多只有O(n)O(\sqrt{n})种长度,所以我们可以遍历每种长度ll然后遍历每个位置ii然后判断从ii开始长度为ll的子串是否是模式串。时间复杂度为O(nm)O(\sqrt{n}m)

方法二:AC 自动机

先将所有模式串加入 AC 自动机,然后再匹配文本串。注意 AC 自动机中要维护 output link(沿 fail link 跳转时第一个模式串)。时间复杂度O(n+m+mn)O(n+m+m\sqrt{n})

方法三:后缀数据结构

后缀数据结构也能是很擅长字符串匹配的,后缀树和后缀自动机都可以解决本题,由于没学过后缀树就只写后缀自动机的做法了:

英文原文

中文翻译

注意后缀自动机是这三种做法中唯一可以在线处理询问的做法,处理单次询问的时间复杂度为O(s+occurrence)O(|s|+occurrence),occurrence 为出现次数。整体时间复杂度O(m+n+mn)O(m+n+m\sqrt{n})

总结

三种做法各有各的优缺点,就本题来看三种做法的时间复杂度相同,时间如下:

  1. AC 自动机 2.55 秒(但我有一种很愚蠢的写法竟然只要 1.32 秒)
  2. 哈希 3.41 秒
  3. 后缀自动机 4.83 秒 (可能因为后缀自动机本身常数比较大)