我正在将一种算法从 Java 移植到 Scala,该算法在VP Tree上进行范围搜索。简而言之,树中的节点具有空间坐标和半径:该半径内的节点可以在左子树上找到,而该半径外的节点可以在右子树上找到。范围搜索尝试在树中查找到查询对象指定距离内的所有对象。
在 Java 中,我向函数传递了一个数组列表,它在其中累积了结果,可能会向下递归其中一个或两个子树。这是 Scala 的直接端口:
def search(node: VPNode[TPoint, TObject], query: TPoint, radius: Double,
results: collection.mutable.Set[TObject]) {
var dist = distance(query, node.point)
if (dist < radius)
results += node.obj
if (node.left != null && dist <= radius + node.radius)
search(node.left, query, radius, results)
if (node.right != null && dist >= radius + node.radius)
search(node.right, query, radius, results)
}
Scala 的默认集合类型是不可变的,我觉得一直打字有点烦人collection.mutable.
,所以我开始研究它。似乎建议使用不可变集合几乎总是可以的:尽管我正在使用此代码进行数百万次查找,但在我看来,复制和连接结果数组会减慢它的速度。
例如,像这样的答案表明需要更“从功能上”解决问题。
那么,我应该怎么做才能以更 Scala 风格的方式解决这个问题呢?理想情况下,我希望它与 Java 版本一样快,但无论如何我都对解决方案感兴趣(并且总是可以分析它们以查看它是否有很大的不同)。
请注意,我才刚刚开始学习 Scala(我想我不妨在一些有用的东西上切齿)但我对函数式编程并不陌生,之前使用过 Haskell(尽管我不认为我很擅长它! )。