由字和分隔符组成的分层字符串的近似字符串匹配

时间:2016-02-11 08:31:14

标签: string algorithm

我正在寻找一种数据结构,它支持根据一组模式匹配字符串,其中字符串代表mqtt topics。字符串被定义为由斜杠字符分隔的单词(“主题级别”)组成。字符串的示例是“topic1 / topic2”或“// topic1 / topic2”,其中包含空主题级别。字符集为UTF-8,不包括“#”和“+”。

模式是主题字符串,但可以包含两个通配符。第一个通配符“#”只能在模式的末尾使用,并匹配任意数量的后续主题,即“a /#”匹配“a /”是前缀的任何字符串。第二个模式“+”匹配单个任意主题。例如,“sport / tennis / +”匹配“sport / tennis / player1”和“sport / tennis / player2”,但不匹配“sport / tennis / player1 / ranking”。此外,因为单级通配符只匹配一个级别,“sport / +”与“sport”不匹配,但它匹配“sport /".

用例是客户注册提供模式的有趣主题。发送消息时,将使用主题字符串发布消息。该字符串必须与注册订阅者匹配,因此我正在寻找一种有效(在空间和时间方面)选择注册模式与发布主题匹配的订阅者的数据结构。

我在考虑使用后缀树或trie,因为这样可以在使用“#”时允许快速前缀匹配。 trie中的节点将包含该字符串的订户,以及一组子字符串的所有订户。这应该允许快速查找精确和前缀查询,但我不知道这是否支持“+”通配符。

我想到的另一种方法是创建一个有向图,其中每个节点包含一个主题和边topic1 -> topic2,如果模式中有子字符串“topic1 / topic2”。通过此图,我可以按主题遍历节点主题。 “+”通配符只是意味着遍历所有孩子。

一个明显的替代方法是正则表达式,它将导致有限状态机,这可能类似于图方法。但是,我希望能找到更快的东西。

该算法应该在mqtt代理中使用,订阅者可以随时注册和注销主题,因此它还必须支持通过添加或删除模式来更新搜索数据结构。

1 个答案:

答案 0 :(得分:1)

Aho-corasick有限状态机支持通配符。您还可以撤消trie并搜索通配符:http://phpir.com/tries-and-wildcards/