0

したがって、これはそれに取り組むための最良の方法ではないかもしれませんが、私の最初の考えは表現のためでした. 次のようなリストがあるとします

List(List('a','b','c'),List('d','e','f'),List('h','i','j'))

文字の行と列を見つけたいと思います'e'.

def findChar(letter: Char, list: List[List[Char]]): (Int, Int) =
  for {
    r <- (0 until list.length)
    c <- (0 until list(r).length)
    if list(r)(c) == letter
  } yield (r, c)

よりエレガントな方法があれば、私はすべて耳にしますが、これの何が問題なのかを理解したいと思います。具体的には、コンパイラがここで私に与えるエラーは

type mismatch;  found   : scala.collection.immutable.IndexedSeq[(Int, Int)]  required: (Int, Int)

に割り当てる行でr。私のイテレータが戻り値の型と一致しないと不平を言っているようですが、これがなぜなのか、どうすればよいのかよくわかりません...

4

2 に答える 2

2

あなたの署名ではfindChar、それが返すことをコンパイラに伝えています(Int, Int)。ただし、for(Scala によって推測される) 式の結果はIndexedSeq[(Int, Int)]、エラー メッセージが示すとおりです。その理由は、式の「反復」ごと(r, c)に afterが生成されるためです (つまり、単一の結果だけでなく、結果のシーケンスを生成している)。yieldfor

編集:に関してはfindChar、次のことができます:

def findChar(letter: Char, list: List[List[Char]]) = {
  val r = list.indexWhere(_ contains letter)
  val c = list(r).indexOf(letter)
  (r, c)
}

これは最も効率的なソリューションではありませんが、比較的短時間です。

編集:または、元のアイデアを再利用します。

def findAll(letter: Char, list: List[List[Char]]) =
  for {
    r <- 0 until list.length
    c <- 0 until list(r).length
    if list(r)(c) == letter
 } yield (r, c)

def findChar(c: Char, xs: List[List[Char]]) = findAll(c, xs).head

どちらの場合も、検索された文字が入力リストに含まれていない場合は例外が発生することに注意してください。

編集:または、次のような再帰関数を自分で記述します。

def findPos[A](c: A, list: List[List[A]]) = {
  def aux(i: Int, xss: List[List[A]]) : Option[(Int, Int)] = xss match {
    case Nil => None
    case xs :: xss =>
      val j = xs indexOf c
      if (j < 0) aux(i + 1, xss)
      else Some((i, j))
  }
  aux(0, list)
}

whereauxは、実際の再帰を実行する (ローカルで定義された) 補助関数です (そして、現在のサブリストである index を記憶していますi)。この実装では、 の結果はNone検索された要素がそこになかったことを示しますが、成功した結果は のようなものを返す可能性がありSome((1, 1))ます。

于 2013-05-15T04:30:02.020 に答える