在列表中查找列表中的所有第一个,然后是所有第二个,然后是所有第三个等的元素

时间:2017-05-17 05:43:50

标签: list haskell matrix transpose

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

cols :: Matrix a -> [Block a]
cols matrix = map (!! n) matrix
 where
  n = (the values 1 .. 9)
  • Matrix被描述为[Rows][[values]]

  • 块被描述为[a]

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

我明白了

map (!! 1) matrix

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

2 个答案:

答案 0 :(得分:3)

  

我明白了

map (!! 1) matrix
  

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

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

即可
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上尝试相同的操作,会发生什么?

答案 1 :(得分:3)

如果我理解正确,你想计算矩阵的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一个空列表,或者第一个为空的列表,那么我们到达转置的末尾,所以我们返回一个空列表

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

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