确定一个通配符字符串是否与集合中的另一个通配符字符串完全匹配


9

这是困扰我一段时间的问题。假设字符串是1和0 的序列,通配符字符串是1、0和?s的序列。所有字符串和通配符字符串具有相同的长度。这些是标准的UNIX通配符。10 ?? 1匹配10011、10111等-a?在该位置匹配1或0。如果和是通配符字符串,那么如果与匹配的每个字符串也与匹配,则我们写。vwvwvw

问题:给定一组通配符字符串和一个查询(也是通配符字符串),是否存在使得吗?如果不是,我们可以有效地将添加到吗?SvwSvwvS

这是显而易见的解决方案(其中是字符串的大小,是RAM的字大小(通常为32或64)):遍历列表中的每个元素并进行测试条件(可以使用位旋转2或3个操作来完成)。还要在扫描时测试是否适合任何。如果未能通过我们的测试,则将添加到集合中,并删除我们标记的。O(kmn)kmvwwvvw

但这还不够快。如果有解决方案,或者在理想情况下,复杂度类似于基数树(),那真的很酷。查询大致正确也可以:即,如果,则返回yes或no;否则,返回false。但是如果条件不成立,则绝对不返回。O(logn)O(k)vw

尽管这并不能解决最坏的情况,但是您可以假定中的所有元素都由通配符字符串限制;也就是说,存在一些,使得对于所有,。SvwSvw

我尝试过的想法

  • 通配符字符串形成联接符号。我们可以有一棵包含通配符字符串的n元树;叶子将是通配符字符串,分支将代表所有子代的联接。如果查询和联接是不可比拟的,那么我们不必浪费时间尝试与该分支的所有子代进行比较。此外,如果我们进行更新,而该更新恰好大于联接,则可以简单地删除整个分支。不幸的是,在最坏的情况下,这仍然是,并且在遍历树中添加元素时,我们并不总是找到建立的“最佳”联接。O(n)
  • 一个可以形成的基数树根。我们知道由一些通配符字符串限制;假设它是0到0。然后,特里树的所有分支只需位于字符串的第1位和第3位。如果查询的当前位是1,则必须检查?。1个分支;如果为0,我们检查?0个分支;如果是?,我们只检查?。科。因为我们必须潜在地采取多个分支,所以这看起来不太好(出于相同的原因很难更新trie)。由于匹配是非常快速的操作,因此与幼稚的策略相比,在树中进行大量遍历会比较麻烦(遵循一堆指针比进行一些OR和AND的代价高得多)。SS

相关工作

  • 在网络社区中,此问题表现为“数据包分类”,这是对已知算法和数据结构的良好概述。不幸的是,几乎总是假设通配符字符串仅匹配前缀,并且查询是此类字符串的元组。当然,我们总是可以转换通用通配符字符串来满足以下条件:1?00?1 ?? 是(1,?,0,0,?,1,?,?)。但是,这将是无效的。做出的另一个假设是,这些元组与“颜色”相关联,并且查询应返回颜色(不仅仅是匹配的颜色)。这使问题变得更加困难,因为我们必须对元组进行排序(否则,(0,?)和(?,1)中的哪一个与(0,1)相匹配是模棱两可的)。

  • 在算法社区中,我发现了很多与查找与“无关”匹配的子字符串相关的结果。这是一个相当困难的问题,我无法真正利用任何技术。

结论

谢谢你的帮助!


1
字符串可以允许多大?而且,为什么不考虑它们的复杂性呢?显然,您需要将字符串Ω(logn) 否则你就不会有 n不同的字符串。如果您允许,似乎也很直观O(n)-length字符串,那么在最坏的情况下,您将不得不查看数据结构中的所有字符串...字符串长度是否有界限?多对数的?o(n)
Artem Kaznatcheev

对不起,如果我不清楚。弦有O(1)尺寸; 出于所有目的和目的,您可以将它们视为32个字符长。“字符串”只是用于解决问题的一种方便的抽象方法-它们实际上表示为(整数,位掩码)元组,以便我可以计算联接和vw仅需少量机器操作。(当然,通过增加整数和位掩码字段的数目,可以自然地将问题扩展到较大的恒定大小的字符串)。
Christopher Monsanto

我的上述评论可能对复杂性参数:( ..如果允许字符串的大小也有所变化,则字符串的大小和集合的大小之间实际上没有任何关系。关于存在是真的 O(n)最糟糕的情况是不幸的,但是无论如何,我对平均情况(或近似值)更感兴趣。
Christopher Monsanto

Answers:


3

如何使用有限状态自动机?语言S是有限的,因此是有规律的。即使经过下面的转换,它仍然是常规的。因此,在执行了将正则表达式转换为确定性有限状态自动机的常规步骤之后,您将拥有一个识别器,可以识别要在其中进行操作的内容O(k)时间。如果以下建议中存在错误,希望该想法仍然可行。

皱纹是如何处理通配符的:?。通配符字符串中的通配符与测试字符串中的0或1匹配。但是由于我们试图识别通配符字符串,所以通配符字符串中的通配符匹配0、1或?。在另一个通配符字符串中。这个集合仍然是规则的,因此我们变换每次出现的?到正则表达式(0 | 1 |?),其中竖线是通常的交替运算符。所以如果你整个S 是{10 ?? 1,0?1?0},结果正则表达式为(10(0 | 1 |?)(0 | 1 |?)1 | 0(0 | 1 |?)1(0 | 1 |?)0)

至于向机器添加字符串,最近有一些工作是逐步更改有限状态自动机。请参阅本文件由Daciuk等人:“最小非周期性有限状态自动机的渐进式构造”。

这有帮助吗?


是的,我曾经考虑过自动机(我对特里树所做的事情类似于使用自动机接受字符串的方式)。但是,我没有找到有关逐步构建所述自动机的工作。我会检查一下,谢谢指针ShyPerson。
Christopher Monsanto

我引用了Daciuk等人的论文,因为它似乎与您要达到的目标最接近。但是我认为值得一提的是,Carrasco和Forcada在其论文“最小有限状态自动机的增量构造和维护”中最近解决了任意有限状态自动机的问题:mitpressjournals.org/doi/abs/10.1162/ …
ShyPerson 2011年

好的,我认为我不会从这个话题中得到更多帮助,所以我接受您的回答。谢谢!
Christopher Monsanto
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.