【问题标题】:Transposing a 2 dimensional matrix in Erlang在 Erlang 中转置二维矩阵
【发布时间】:2011-07-20 08:13:23
【问题描述】:

给定一个像下面这样的矩阵,将它转换成 90 度角到下面的第二个矩阵。您将如何以最干净的方式执行此操作?简短/简洁/清晰的解决方案,易于掌握。

来自

[[A1,A2,A3],
 [B1,B2,B3],
 [C1,C2,C3]]

[[A1,B1,C1],
 [A2,B2,C2],
 [A3,B3,C3]]

编辑:我意识到最初的问题并不清楚。我想知道如何在 Erlang 中做到这一点。

【问题讨论】:

  • 这称为转置矩阵:a[j,i] = a[i, j]
  • 谢谢;我正在更改标题。

标签: functional-programming erlang


【解决方案1】:

简化已经给出的解决方案,你可以做到:

-module(transp).

-export([transpose/1]).

transpose([[]|_]) -> [];
transpose(M) ->
  [lists:map(fun hd/1, M) | transpose(lists:map(fun tl/1, M))].

【讨论】:

  • 经过测试的解决方案 - 这就是我的想法。
  • 我喜欢这个解决方案,非常简洁优雅,而且很容易让自己相信它一定是正确的。
【解决方案2】:

这是我认为我从 Haskell 标准库中获得的一个实现:

%% Transpose rows and columns in a list of lists. Works even if sublists
%% are not of same length. Empty sublists are stripped.
transpose([[X | Xs] | Xss]) ->
    [[X | [H || [H | _] <- Xss]]
     | transpose([Xs | [T || [_ | T] <- Xss]])];
transpose([[] | Xss]) -> transpose(Xss);
transpose([]) -> [].

紧凑且略微令人费解。

【讨论】:

  • 对于任何好奇的人,Elixir 版本将是:def transpose([[x | xs] | xss]), do: [[x | (for [h | _] &lt;- xss, do: h)] | transpose([xs | (for [_ | t] &lt;- xss, do: t)])] 您应该能够轻松地从上面翻译其余部分。我无法在此处粘贴整个内容,因为 Stupid Stackoverflow Comment Limitations™
【解决方案3】:

这是我的示例解决方案:

-module(transp).

-export([transpose/1]).

transpose(L) ->
     transpose_do([], L).

transpose_do(Acc, [[]|_]) ->
     lists:reverse(Acc);
transpose_do(Acc, M) ->
     Row = lists:foldr(
          fun(Elem, FoldAcc) ->
                    [hd(Elem) | FoldAcc]
          end,
          [],
          M),
     transpose_do([Row|Acc], lists:map(fun(X) -> tl(X) end, M)).

测试:

1> M = [[a1,a2,a3],[b1,b2,b3],[c1,c2,c3]].
[[a1,a2,a3],[b1,b2,b3],[c1,c2,c3]]
2> transp:transpose(M).   
[[a1,b1,c1],[a2,b2,c2],[a3,b3,c3]]

【讨论】:

  • 顺便说一句,它适用于任何大小的矩阵,不仅适用于方阵; e. G。 [[a1,a2,a3,a4], [b1,b2,b3,b4], [c1,c2,c3,c4], [d1,d2,d3,d4]] 也可以作为输入 ;-)
  • 这确实是一个不错的答案!
  • 当然,我在上面的第一条评论中指的是[[a1,a2,a3], [b1,b2,b3], [c1,c2,c3], [d1,d2,d3]]
【解决方案4】:

在函数式编程语言中,矩阵转置的常用方法是使用unzip

【讨论】:

  • 谢谢。这似乎指向了正确的方向,但在实践中我仍然看不到如何做到这一点。
  • 如果您将示例从列表列表转换为三元组列表,则可以直接使用unzip3 进行实验。一旦你了解了unzip 的工作原理,编写一个带有列表列表的unzip 版本应该很简单。
  • 但是 unzip/1unzip/3 分别限于二维和三维矩阵。 stdlib 中没有unzip4unzip5 等:-(
  • 这也是我的问题,无法概括解压缩版本。
【解决方案5】:

您展示的不是矩阵旋转,而是矩阵转置。如果你调用第一个矩阵 A 和第二个 B 那么你有

A[i,j] = B[j,i]

要从 A 转到 B,您只需要两个嵌套循环,其中 i = 1 到 n 和 j = i+1 到 n,并且在每次迭代时,您使用临时变量交换非对角线条目。

【讨论】:

  • 是的,但问题是如何在 Erlang 中做到这一点。
猜你喜欢
  • 2012-01-22
  • 2014-11-29
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 2017-06-06
  • 2020-03-03
相关资源
最近更新 更多