【问题标题】:Pattern matching in brace expressions formulas大括号表达式公式中的模式匹配
【发布时间】:2013-01-31 15:21:09
【问题描述】:

我有一长串 n (~50000) 行的公式,看起来像这样:

A(1, 2) = 54353
A(1, 2, 3) = 89327
A(1, B(1, 2)) = 8372
A(7, B(1, 3, 5)) = 6311
A(7, B(C(1, 3, 7), 2, C(1, 3), 5)) = 28490
B(A(1, C(5, 3)), 3, 8, D(1, 2)) = 39783

等等

这些公式包含文字(即1235 等)和函数调用(即A(x, y)A(x, y, z)B(x, y)),其中函数的参数也可以是文字或其他(嵌套)函数调用。函数(即ABC 等)是固定的,数量并不多(可能有十几个)。

现在我已经使用完整公式或带有 * 的某种模式运行查询,它应该充当全局字符,即:

A(1, 2) => [54353]
A(1, *) => [54353, 89327, 8372]
A(*, 3) => [89327]
A(*, B(*)) => [8372, 6311, 28490]
A(*, B(*, 3, *)) => [6311]

基本上,我有两个问题:

  1. 怎么做根本:事实上,我不知道这里有一个好的基本模式匹配算法。我尝试将带有 * 的表达式转换为正则表达式,它适用于简单的示例,但唉,对于更复杂的示例来说失败了,即:

    Converting:
    'A(*, B(*, 3, *))' => /^A\(.*, B\(.*, 3, .*\)\)$/
    
    True positive:
    'A(7, B(1, 3, 5))' =~ /^A\(.*, B\(.*, 3, .*\)\)$/
    
    False positive:
    'A(7, B(C(1, 3, 7), 2, C(1, 3), 5))' =~ /^A\(.*, B\(.*, 3, .*\)\)$/
    

    我觉得将这些大括号表达式转换为反向波兰表示法,然后应用正常的正则表达式方法可能会有所帮助,但我不确定。

  2. 如何做到这一点快速:任何比为每个查询进行约 50000 次匹配更快的想法都非常受欢迎。是否可以在这里使用某种 FSM?

【问题讨论】:

    标签: algorithm tree pattern-matching expression fsm


    【解决方案1】:

    正则表达式是为Regular Languages(最初)设计的,而您描述的是Context Free Language

    Deterministic Push-Down Automata 可以解析您的语言。

    这个想法类似于 FSM,但除此之外,您还有一个 stack,您可以使用 push()pop() 元素。
    在 FSM 中更改状态也取决于堆栈的头部。

    【讨论】:

    • 确实如此。您能推荐一些现有的 PDA 实现吗?
    猜你喜欢
    • 2014-01-25
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2018-08-05
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多