大量模式的数据结构

时间:2015-04-21 17:05:36

标签: algorithm data-structures pattern-matching

在一次采访中,我被要求提出可以容纳数百万个模式的数据结构,并通过它们快速搜索以找到最长的匹配模式。

例如,模式如下:

1- 8876 8893 87          | true
2- 8876 889              | false
3- 8876 8                | false
4- 887                   | true

输入是一个至少有2位且最多18位的数字,我们需要从数据结构中找到最长的匹配模式,并在最后提取布尔值。

例如,8876 8893 9943 531匹配,并返回true8876 8397 5430 743匹配,并返回false

我的回答是使用一棵树,每个级别都有key value对的列表。作为数字和值的键是null或等于布尔值,具体取决于它是否是模式的结尾。像:

# matching 8875
# start the search by first digit
[..., (7, null), (8, null), (9, null)] 
                  ^
                 [..., (7, null), (8, null), (9, null)] 
                                   ^
                                   [..., (7, true), (8, null), ...]
# at the last step because we don't have a pattern 
# to match the digit 5, we return the `true` from (7, true)

具有挑战性的部分是,模式非常多。数以百万计。这有什么好处吗?如果没有,你的建议是什么。

2 个答案:

答案 0 :(得分:3)

非常好的数据结构非常适合您描述的问题,即许多条目共享公共前缀(和/或后缀)的集合结构,以及基于共享前缀执行搜索的位置是Trie

  

computer science中, trie ,也称为数字树,有时也称为radix tree前缀树(如它们可以通过前缀来搜索,是一种有序的树数据结构,用于存储动态集或关联数组,其中键通常是字符串。与二叉搜索树不同,树中没有节点存储与该节点关联的密钥;相反,它在树中的位置定义了与之关联的键。节点的所有后代都具有与该节点关联的字符串的公共prefix,并且根与空字符串相关联。值通常不与每个节点相关联,只与叶子和一些与感兴趣的键对应的内部节点相关联。有关前缀树的空间优化表示,请参阅compact prefix tree

具体来说,紧凑型前缀树或 patricia trie 似乎非常适合您的问题。

鉴于所提到的类型的尝试通常用于存储与键相关联的值,如果您的问题不需要(即,您不需要存储输入模式字符串的原始索引并在搜索中返回该值),有一个密切相关的解决方案可能更适合。正如@JimMischel在评论中指出的那样, Aho–Corasick string matching algorithm 构建了一个类似于trie的结构,并在内部节点之间增加了链接。如果要匹配的模式集是固定的,并且构建了数据结构,那么对于搜索,其运行时间在输入长度和匹配条目数方面是线性的。

在这个问题Aho Corasick algorithm

中讨论了这个问题

您可以在线找到一些实现,例如C#JavaHaskell

答案 1 :(得分:0)

你可以考虑实现wu-manber,这对代码和内存的效率也很简单。