- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我正在考虑的应用程序,将有一个大型(100,000+)树“数据库”(想想编程语言中的表达式,或 S 表达式),并且我需要在该数据库中查询以下表达式:匹配特定的给定表达式。
在提供我想要的详细信息之前,请注意,我希望获得与索引一大组树以优化子树查找相关的任何信息。
在我的具体情况下(这将是 Metamath 证明助手使用的后端),表达式具有以下结构(采用类似 Haskell 的表示法):
data Expression = Placeholder Id | VarName Id | ConstName Id [Expression]
或者作为 S 表达式形式的 BNF:
Expression = '?' Id | Id | '(' Id Expression* ')'
其中 Id
是某种标识符。
例如,我可以有一个包含如下表达式的数据库
(equiv ?ph ?ps)
(not (in (appl (sqrt) (2)) (Q)))
(equiv (eq ?A ?B) (forall ?x (equiv (in ?x ?A) (in ?x ?B))))
在此上下文中,如果可以通过用表达式替换占位符来使两个表达式相等,则它们匹配。因此,在上述迷你数据库中查找 (equiv (eq A (emptyset)) ?ph)
将得到第一个和最后一个表达式。
再说一遍:我如何在一大堆带有占位符的(表达式)树中实现快速查找?我可以使用什么样的索引数据结构?
最佳答案
我将使用 trie 来实现查找。每个 key 将包含以下内容之一:
这些应该以某种方式排序 - 可能是占位符,然后是所有 ConstNames(字母顺序),然后是变量(范围排序,然后是参数顺序),然后是 ConstValues(数字顺序)。只要 trie 中有具体的使用顺序,就可以了。
遍历表达式的树,在遇到适当的键时将其注入(inject)到 trie 中。对要插入数据结构中的所有表达式执行此操作。当需要查询它时,您可以以类似的方式遍历 trie,但使用一些新规则。
现在,这确实意味着当您遇到占位符时,搜索空间可能会有所“爆炸”,但您可以做一件事来尝试在实践中减轻这种情况。以广度优先的方式遍历表达式的树(在构造 trie 和查询中)。这意味着,如果其中一个参数是占位符,则您不必全面深度搜索与该表达式匹配的每个子树到目前为止 - 相反,您可以跳转到下一个参数 - 这可能不会是一个占位符,因此将大大减少搜索空间(与匹配“所有内容”相比)。
为了完整起见,让我们举一个例子
(not (in (appl (sqrt) (2)) (Q)))
并从中创建一个特里条目-
not -> in -> apply -> "Q" -> sqrt -> 2
添加 (不是(in ?ph E))
到此将导致 -
not -> in -> apply -> "Q" -> sqrt -> 2
\-> ?ph -> "E"
继续以这种方式将表达式注入(inject)到 trie 中。同样以这种方式遍历进行查询,直到到达 trie 中搜索的末尾,然后返回匹配的内容。
注意 - 这些条目的唯一性基于您不必支持可变参数函数的假设。如果这样做,请为每个键附加一些上下文信息(阅读下一段以了解如何执行此操作的信息)以区分哪些参数进入哪些函数
我忽略了一个细节——变量。如果您只想在它们是完全相同的变量名时进行匹配,则无需进行任何工作。但这可能不是您想要的;您可能希望它匹配通用变量,只要它们彼此“一致”即可。执行此操作的方法是为每个变量分配一个标识符,该标识符表示首次定义该变量的范围。
最简单的方法就是根据其祖先的参数顺序的串联组成一个标识符。也就是说,如果一个变量首先被定义为函数的第二个参数,而该函数又是根函数的第五个参数,那么我们可以将其标记为 ( 5, 2)
或 (2, 5)
,以更直观的方式为准。无论哪种方式,这都将确保为变量提供一致的标识符,而不管其他地方的其他变量/函数如何。然后使用这个新变量名称正常进行。
关于indexing - 使用占位符快速查找树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45627314/
如何更改循环中变量的名称?比如 number1 、 number2 、 number3 、 number4 ? var array = [2,4,6,8] func ap ( number1: Int
我想设置 View 的背景颜色并在一定延迟后将其更改为另一种颜色。这是我的尝试方式: print("setting color 1") self.view.backgroundColor = UICo
我在使用 express-session 时遇到问题。 session 数据不会在请求之间持续存在。 正如您在下面的代码中看到的那样,/join 路由设置了一些 session 属性,但是当 /sur
我试图从叶渲染器获得一个非常简单的结果,用于快速 Steam 的 for 循环。 我正在上传叶文件 HTML,因为它不接受此处格式正确的代码 - 下面的pizza.swift代码- import
你们中有人有什么好的链接可以与我分享吗?我正在寻找一个 FAST 程序员编辑器,它可以非常快速地打开包含超过 100, 000 行代码的文件?我目前正在使用记事本自动取款机,打开一个 29000 行长
我现在正在处理眼动追踪数据,因此拥有一个巨大的数据集(想想数百万行),因此希望有一种快速的方法来完成此任务。这是它的简化版本。 数据告诉您眼睛在每个时间点正在查看的位置以及我们正在查看的每个文件。 X
我是新手,想为计时器或其他设备选择提示音。 如何打开此列表,以选择其中一种声音? Alert sound list 最佳答案 您将无法在应用中使用系统声音。 但是,您可以包括自己的声音文件,并将其显示
我编写了以下代码来构建具有顺序字符串的数组。 它的工作方式与我预期的一样,但我希望它能更快地运行。有没有更有效的方法在PowerShell中产生我想要的结果? 我是PowerShell的新手,非常感谢
我有一个包含一些非唯一行的矩阵,例如: x 尝试 y <- rle(apply(x, 1, paste, collapse = " ")) # y$lengths is the vector con
我的函数“keyboardWillShown”有问题。所以我想要的是菜单打开时,菜单正好出现在键盘上方。它可以在Iphone 8 plus,8、7、6上完美运行。但是,当我在模拟器上运行Iphone
我正在尝试通过Swift 5中的HTTP get方法从API提取数据。它在启动时成功加载了数据,但是当我刷新页面时,它说“索引超出范围”,这是因为数据是不再会在我的日志中读取,因此索引中没有任何内容。
我想做什么: 从我的数据库中获取时间戳并将其转换为用户的时区。 我的代码: let tryItNow = "\(model.timestampName)" let format = D
给定字体名称和字体大小,如何查找字符串的宽度(CGFloat)? (目标是将UIView的宽度设置为足以容纳字符串的宽度。) 我有两个字符串:一个重复“1”,重复36次,另一个重复“M”,重复36次。
我正在尝试解析此JSON ["Items": ( { AccountBalance = 0; AlphabetType = 3; Description = "\U0631\U
我在UINavigationBar内放置了一个UILabel。 我想根据navigationBar的高度增加该标签的字体大小。当navigationBar很大时,我希望字体大小更大;当滚动并缩小nav
我想将用户输入限制为仅有效数字并使用以下内容: func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, rep
目前我有一个包含超过 100.000 张图像的数据库,它们大小不一或类似,但我想为我的公司制作以下内容: 我插入/上传一张图片,系统返回最有可能相同的图片。我不知道使用什么算法,但它需要快速。我可以预
在我的 swift 项目中,我有一个按钮,我想在标签上打印按下该按钮的时间。 如何解决这个问题? 最佳答案 添加到DHEERAJ的答案中,您只需在func press(sender: UIButton
我必须发表评论,尝试在解析中导入数组。然而,有一个问题。 当我尝试从 Parse 加载数组时,我的输出是 ("Blah","Blah","Blah")这是一个元组...而不是一个数组 TT... 如何
我的应用程序有一个名为 MyDevice 的类,我用它来与硬件通信。该硬件是可选的,实例变量也是可选的: var theDevice:MyDevice = nil 然后,在应用程序中,我必须初始化设备
我是一名优秀的程序员,十分优秀!