二维列表如下所示:
1 | 2 | 3
- - - - -
4 | 5 | 6
- - - - -
7 | 8 | 9
或纯属Haskell[ [1,2,3], [4,5,6], [7,8,9] ]
diagonals [ [1,2,3], [4,5,6], [7,8,9] ]
的预期输出为[ [1], [4, 2], [7, 5, 3], [8, 6], [9] ]
编写allDiagonals
(包括反对角线)很简单:allDiagonals :: [[a]] -> [[a]]
allDiagonals xss = (diagonals xss) ++ (diagonals (rotate90 xss))
我对这个问题的研究StackOverflow上的类似问题
Hoogle
搜索
[[a]] -> [[a]]
没有给我有趣的结果。独立思考
我认为索引遵循的是基数x中的一种计数,其中x是矩阵中的维数,请看:
1 | 2
- - -
3 | 4
对角线为[ [1], [3, 2], [4] ]
1
可在matrix[0][0]
上找到3
可在matrix[1][0]
上找到2
可在matrix[0][1]
上找到1
可在matrix[1][1]
上找到这类似于以2为基数最多3,即矩阵大小减去1。但这太模糊了,无法翻译成代码。
最佳答案
从universe-base-1.0.2.1开始,您可以简单地调用 diagonals
函数:
Data.Universe.Helpers> diagonals [ [1,2,3], [4,5,6], [7,8,9] ]
[[1],[4,2],[7,5,3],[8,6],[9]]
完整的实现如下所示:
diagonals :: [[a]] -> [[a]]
diagonals = tail . go [] where
-- it is critical for some applications that we start producing answers
-- before inspecting es_
go b es_ = [h | h:_ <- b] : case es_ of
[] -> transpose ts
e:es -> go (e:ts) es
where ts = [t | _:t <- b]
关键思想是,我们保留两个列表:一个尚未开始检查的矩形块,以及一个五边形块(切出左上三角形的矩形!)。对于五边形块,从每个列表中选择第一个元素会给我们另一个对角线。然后,我们可以在删除该对角线后从矩形未检查的块中添加一个新行到剩余的行。
该实现可能看起来有点不自然,但它的意图是非常高效和懒惰:我们要列出的唯一内容是将它们分解为头部和尾部,因此该元素的总数应为O(n)。矩阵;并且我们在完成结构分解后就立即生成元素,因此对于垃圾回收而言,它是非常懒惰/友好的。它对于无限大的矩阵也适用。
(我仅为您推送了此发行版:您可以使用的最接近的方式是使用
diagonal
,它只会为您提供[1,4,2,7,5,3,8,6,9]
而没有您想要的额外结构。)关于haskell - 在Haskell中获取矩阵的所有对角线,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32465776/