首先找到所有,然后是所有第二,然后是所有第三等列表中列表的元素

Find all first, then all second, then all third etc. elements of lists in a list

使用 (9x9) 矩阵的自制定义,描述为 Maybe Int 列表的列表。我想创建一个 return 矩阵的 9 列的函数。我想这样做:

cols :: Matrix a -> [Block a]
cols matrix = map (!! n) matrix
 where
  n = (the values 1 .. 9)

所以我希望输出是列表的列表,其中这些列表是行的第一个元素、行的第二个元素等的列表。

我看到了

map (!! 1) matrix

将return 行的第二个元素的列表,即矩阵的第二列;但我不知道如何在一个很好的函数中将其扩展到矩阵的所有列。

I see that

map (!! 1) matrix

Will return a list of the second elements of the rows, ie the second column of the matrix; but I don't know how to extend this to all the columns of the matrix in a nice function.

如果这是您想要的方式,您只需将其更改为

map (!!i) matrix

[map (!!i) matrix | i <- [0.. length (matrix!!0) - 1]]

例如

Prelude> let matrix = [[1,2,3],[4,5,6]]
Prelude> [map (!!i) matrix | i <- [0.. length (matrix!!0) - 1]]
[[1,4],[2,5],[3,6]]

当然,这个问题的复杂性不必要地高,因为 !! 的复杂性在其参数中是线性的。相反,您可以按如下方式构建递归函数:

  • 假设你将矩阵的每个元素分别拆分为headtail

  • 转置矩阵中所有拟合元素的head在哪里?

  • 如果你现在对所有元素的 tail 尝试同样的事情会发生什么?

如果我没理解错的话,你要计算矩阵的transpose :: [[a]] -> [[a]]

import Data.List(transpose)

cols :: [[a]] -> [[a]]
cols = transpose

您可以按如下方式有效地实现:

cols :: [[a]] -> [[a]]
cols [] = []
cols ([]:_) = []
cols l = (map head l) : cols (map tail l)

此代码仅适用于矩形矩阵。代码的工作方式如下:如果我们给 cols 一个空列表,或者第一个 为空的列表,那么我们到达了转置的末尾,所以我们 return 一个空列表。

如果另一方面仍然有一个列表,并且第一行包含一个元素(并且由于矩阵是正方形的,所以另一个也是),我们首先将所有行的 head 作为列,然后对行的 tail 执行递归以计算剩余的列。

该函数在 O(n) 中工作,其中 n 元素的数量 (不是 rows/columns) 的矩阵。或者 O(r×c) 其中 r 行数和 c 列数。