我正在寻找一种有效的数据结构,该结构允许字符串与模式匹配。模式遵循类似于语法的正则表达式,但允许递归。它们包含可选,选择和递归/通配符。模式的一些示例是:
how many * (are coming|came) to (the)? party
(drunk|sober)? people
annoying *
这些模式将与以下字符串匹配:
how many drunk people are coming to the party
how many people came to party
how many annoying drunk people are coming to the party
对于那些失败,将会失败:
how many are coming to the party <-- expected something else after 'many'
drunk sober people <-- has to be either 'drunk' or 'sober' but not both
语法与正则表达式基本相同。除了*
期望在该位置有另一个匹配的模式。 ()
是一个简单的组。 ()?
是一个可选组。 (choice1|choice2)
是一个选择组。
有关模式/输入的更多信息:
要求:
天真解决方案1 将所有模式存储在数组中,并尝试一个接一个地匹配,直到我们成功或到达列表的末尾。递归会非常缓慢。所以不是一种选择。
天真的解决方案2 从所有可能的模式构建前缀/ patricia / ... trie,并包括一些用于通配符的特殊节点。这样比较好,但是每个可选/选择组都会创建其他模式。这使得树很快“爆炸”。尤其是因为它将创建许多分支,这些分支在根部附近不同但在叶部附近非常相似。
更复杂的解决方案 根据模式中的单词创建特里,并为其分配唯一索引。使用trie,我们可以将输入字符串转换为整数序列。但是然后我需要一些方法来将整数与模式进行匹配。不太确定该怎么做。
我觉得应该有一个解决这类问题的好方法。我猜想树表示是正确的选择,但是我找不到适合任务的任何算法/数据结构。有没有人为我解决过类似的问题和一些建议?
注意:这只是我的玩具项目。我不是在寻找某种生产质量工具,我也不是很在意我要花多长时间来实施它。只是好奇是否存在一个好的解决方案。
答案 0 :(得分:0)
这似乎是context-free grammars的特例。不幸的是,由于可能存在歧义,因此您的定义并未将其进一步限制为deterministic context-free grammar。据我所知,最好的选择是Earley parser或CYK algorithm。