我正在尝试评估不同的子串搜索(ala strstr)算法和实现,并寻找一些精心设计的针和干草堆字符串,以捕捉最坏情况的性能和可能的角落错误。我想我可以自己解决这个问题,但我认为有人必须在某个地方找到很多测试用例......
答案 0 :(得分:3)
对自己的一些想法和部分答案:
蛮力算法的最坏情况:
a^(n+1) b
中的 (a^n b)^m
e.g。 aaab
aabaabaabaabaabaabaab
SMOA的最坏情况:
yxyxyxxyxyxyxx
中(yxyxyxxyxyxyxy)^n
之类的内容。需要进一步完善。我试图确保每个进度只是部分匹配长度的一半,并且最大后缀计算需要最大量的回溯。我很确定我是在正确的轨道上,因为这种类型的案例是我迄今为止发现的唯一方法,使我的SMOA(渐近6n+5
)的实现比glibc的双向运行慢(渐近2n-m
,但预处理开销有中等程度的痛苦。)
基于滚动哈希的最坏情况:
无论字节序列是什么导致哈希与针的哈希冲突。对于任何合理快速的哈希和给定的针,应该很容易构造一个干草堆,其哈希在每个点与针的哈希碰撞。但是,似乎很难同时创建长部分匹配,这是获得最坏情况行为的唯一方法。当然,对于最坏情况的行为,针必须具有一定的周期性,以及通过仅调整最终字符来模拟散列的方法。
双向的最坏情况:
似乎是非常短的针具有非平凡的MS分解 - 类似于bac
- 其中大海捞针在针的右半部分中包含重复的假阳性 - 类似于dacdacdacdacdacdacdac
。这种算法可能很慢的唯一方法(除了glibc作者实现它之外......)是通过使外循环迭代多次并重复产生开销(并使设置开销很大)。
其他算法:
我真的只对空间O(1)
的算法感兴趣,并且预处理开销很低,所以我没有那么多关注它们的最坏情况。至少Boyer-Moore(未经修改使其成为O(n)
)有一个非常重要的最坏情况,它变为O(nm)
。
答案 1 :(得分:0)
不直接回答你的问题,但你可能会发现书中的算法 - 字符串,树和序列算法:计算机科学和计算生物学 - 有趣(在子字符串搜索上有许多新颖的算法)。此外,它也是特殊和复杂案件的良好来源。
答案 2 :(得分:0)
一个可能提供有趣统计数据的程序,但我现在没时间进行测试:
随机化字符串长度, 然后随机化该长度的字符串内容, 然后随机化一个子串的偏移/长度(可能不在字符串中), 然后随机地破坏子串(可能根本没有), 重复。
答案 3 :(得分:0)
您可以通过以下方式递归生成容器字符串(分别包含测试值),
从空字符串开始,通过向左侧或右侧(两者)添加字母表中的字符,生成当前集合中字符串扩充所给出的所有字符串。
用于生成容器字符串的字母表由您选择。
您为包含的字符串测试2个字母。一个是组成容器字符串的,另一个是它的补充。