【问题标题】:Find all first, then all second, then all third etc. elements of lists in a list首先查找所有列表,然后是所有第二个,然后是所有第三个等。列表中的列表元素
【发布时间】:2017-10-16 10:09:59
【问题描述】:

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

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

  • 块被描述为[a]

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

我明白了

map (!! 1) matrix

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

【问题讨论】:

  • 为了参考(我意识到你的目标是自己实现它):你想transpose the list of lists
  • 这完全正确,一开始我没有意识到 transpose 是这样做的,但@Ami Tavroy 正在使用我想了解更多的确切方法。谢谢你们!

标签: list haskell matrix transpose


【解决方案1】:

我明白了

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 不错。出于好奇,处理不规则矩阵的“haskonic”方式是什么?
    • @AmiTavory 首先确定您想要的参差矩阵的输出,然后找到该目标的良好实现。也就是说,有很多合理的方法可以“转置”不是矩阵的列表列表,并且在您选择其中一个之前,您无法寻找惯用的解决方案。
    • @AmiTavory:我认为问题确实在于您如何定义不规则矩阵的转置。如果您按列查看矩阵,那么您会发现存在间隙。如何处理这些差距?
    • 为什么不像内置的transpose 那样,把它们粘在上面:transp [] = [] ; transp xs = concatMap (take 1) xs : transp (filter (not.null) (map (drop 1) xs))。 @AmiTavory
    • 感谢大家对评论的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多