受最近有关Haskell中2d网格的问题的启发,我想知道是否有可能创建二维 zipper 来跟踪列表列表中的位置。列表上的一维 zipper 使我们能够真正有效地在大列表中本地移动(常见示例是文本编辑器)。但是,可以说我们有这样的第二个维度:

grid =
    [[ 1, 2, 3, 4, 5]
    ,[ 6, 7, 8, 9,10]
    ,[11,12,13,14,15]
    ,[16,17,18,19,20]
    ,[21,22,23,24,25]]

我们是否可以创建某种 zipper 数据结构来在此处的网格中不仅有效地左右移动,还可以上下移动?如果是这样,如果我们用无限列表的无限列表替换列表,该怎么办,我们仍然可以获得有效的移动吗?

最佳答案

不完全不。 zipper 工作方式的关键方面之一是,它们通过用于到达 zipper 的路径代表结构中的位置,再加上沿路径创建的额外片段,最终结果是您可以沿该路径回溯并按以下方式重建结构你走。通过数据结构可用的路径的性质因此限制了 zipper 。

因为位置是由路径标识的,所以每个不同的路径都代表一个不同的位置,因此,具有多个指向相同值的路径的任何数据结构都不能与 zipper 一起使用-例如,考虑使用循环列表或任何其他具有循环的结构路径。

2D空间中的任意移动并不能完全满足上述要求,因此我们可以推断出2D zipper 一定受到限制。例如,也许您会从原点开始,沿着结构走一条路径,然后沿该路径回溯一定距离,以便到达其他点。这也意味着对于结构中的任何点,还有其他点只能通过原点到达。

您可以做的是在数据结构中建立2D距离的概念,这样当您沿着结构的路径向下移动时,“下方”的点彼此靠近;这样做的目的是最大程度地减少在2D空间中移动短距离所需的平均回溯量。最终,这与按距离搜索2D空间所需的方法大致相同-最近邻搜索,有效的几何相交之类的东西-并可以使用相同类型的数据结构space partitioning完成,以创建更高的维搜索树。就像其他任何树一样,为quadtreekd-tree或类似结构实现 zipper 很简单。

关于haskell - 二维 zipper ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8905030/

10-11 21:35