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 を基礎となる 1 次元配列 (存在する唯一の配列) として表し、その構造を行と列で別々に表すことをお勧めします。

これにより、表現とアクセスの両方で柔軟性が向上します。たとえば、行優先の組織と列優先の組織の両方を指定できます。行優先の組織か列優先の組織かに関係なく、行反復子の生成は列反復子の生成と同じくらい簡単です。

于 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 に答える