algorithm - 大括号表达式公式中的模式匹配

标签 algorithm tree pattern-matching expression fsm

我有一长串 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?

最佳答案

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

您的语言可以通过确定性 Push-Down Automata 进行解析.

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

关于algorithm - 大括号表达式公式中的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14629140/

相关文章:

c# - 查找大约相同数字的最大数量c#

ios - 我如何实现一个 "dispatch_once"方法,不是针对多线程环境,而是在满足所有条件时只运行一次

algorithm - 为什么当输入规模较小时,插入排序比快速排序快?

r - 选择具有类似 grep 部分匹配的 data.table 列

scala - 如何在 Scala 中抑制 "match is not exhaustive!"警告

c# - 将 C++ 函数转换为 C#

从路径列表中表示文件系统(文件/目录)的 Java 树

haskell - 在 Haskell 中转换一棵树

c - 指针指向指针的二叉树递归插入

python - 使用滚动窗口准确检测数据帧中具有重复值(相同头部和相同尾部)的序列