0

我有存储不同类型矩阵的代码,例如m1: Array[Array[Double]], m2: List[List[Int]]. 正如所见,这些矩阵都存储为一系列行。任何行都很容易检索,但在我看来,列需要遍历矩阵。我想编写一个非常通用的函数,它从这两种类型的矩阵中返回一列。我已经以多种方式编写了此内容,其中最新的是:

/* 获取存储在行中的任意矩阵的列 */

private def column(M: Seq[Seq[Any]], n: Int, c: Seq[Any] = List(),
                     i: Int = 0): List[Any] = {
    if (i != M.size) column(M, n, c :+ M(i)(n), i+1) else c.toList

这可以编译,但它不起作用:当我尝试传入 Array[Array[Double]] 时出现类型不匹配。我也试过用一些视图边界来写这个,即

private def column[T1 <% Seq[Any], T2 <% Seq[T1]] ...

但这也没有结果。为什么我写的第一个代码段不起作用?做这个的最好方式是什么?

4

4 回答 4

2
import collection.generic.CanBuildFrom

def column[T, M[_]](xss: M[M[T]], c: Int)(
  implicit cbf: CanBuildFrom[Nothing, T, M[T]],
           mm2s: M[M[T]] => Seq[M[T]],
           m2s: M[T] => Seq[T]
): M[T] = {
  val bf = cbf()
  for (xs <- mm2s(xss)) { bf += m2s(xs).apply(c) }
  bf.result
}
于 2013-01-16T18:40:23.337 回答
1

我建议您将 Matrix 表示为底层的一维数组(唯一的数组类型!),并根据行和列分别表示其结构。

这为您在表示和访问方面提供了更大的灵活性。例如,您可以同时提供以行为主和以列为主的组织。生成行迭代器与生成列迭代器一样容易,无论它是行优先还是列优先组织。

于 2013-01-17T04:39:00.850 回答
1

如果您不关心返回类型,这是一种非常简单的方法:

  def column[A, M[_]](matrix: M[M[A]], colIdx: Int)
    (implicit v1: M[M[A]] => Seq[M[A]], v2: M[A] => Seq[A]): Seq[A] =
    matrix.map(_(colIdx))
于 2013-01-17T18:22:06.997 回答
0

试试这个:

private def column[T](
 M: Seq[Seq[T]], n: Int, c: Seq[T] = List(), i: Int = 0): List[T] =
   if (i != M.size) column(M, n, c :+ M(i)(n), i+1) else c.toList
于 2013-01-16T18:28:35.247 回答