2016-04-14 16 views
0

再帰を使用してhereから問題13を解決しようとしていますが、エラーが発生します(これはわかりません)。繰り返し数を数えるリストを変換する

問題がある:

List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)

が、私は繰り返し要素を返すとカウントする必要がある次のリストを考える:

object P13 extends App { 

    val ls2 = List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e) 

    println(ls2) 
    println(encodeDirect(ls2)) 

    def encodeDirect[A](ls: List[A]): List[(Int,A)] = ls match { 
     case h :: tail => (ls.takeWhile(_ == h).count(_), h) +: encodeDirect (ls.dropWhile (_ == h)) 
     case Nil => Nil 
    } 

} 

List((4,'a), (1,'b), (2,'c), (2,'a), (1,'d), (4,'e))

は、これは私のコードです

これはエラー:

P13.scala:18: error: type mismatch; 
found : List[(Any, A)] 
required: List[(Int, A)] 
     case h :: tail => (ls.takeWhile(_ == h).count(_), h) +: encodeDirect 
(ls.dropWhile (_ == h)) 
                   ^
one error found 

どうしてこの問題が解決されましたか?

答えて

1

あなたの間違いがあなたの代わりにsize/lengthcountを使用し、非常に簡単です:sizeはちょうどコレクションの長さを返しながら

def encodeDirect[A](ls: List[A]): List[(Int,A)] = ls match { 
    case h :: tail => (ls.takeWhile(_ == h).size, h) +: encodeDirect (ls.dropWhile (_ == h)) 
    case Nil => Nil 
    } 

countは、述語を取り、その述語に一致する要素の数を計算します。

楽しみのためだけに、ここでspanを利用して代替が、接頭辞/接尾辞にコレクションを壊すこと、である:

def encodeDirect[A](ls: List[A]): List[(Int,A)] = 
    ls.headOption.map(h => ls.span(h == _)).toList 
    .flatMap { case (pref, t) => (pref.size, pref.head) :: encodeDirect(t) } 

また、使用して、末尾再帰の方法でこの機能を書き換えるのは良い考えかもしれテール再帰はスカラーではより効率的です。 spanを使用して

+0

'count(_)'はすべての述語に一致し、 'size'と同等であってはなりませんか? – ps0604

+0

@ ps0604、実際には、 'count'の述語関数は' T => Boolean'なので、おそらく 'count(_ => true)'が必要でした。これは 'size'と同等ですが、それほど効率的ではありません。 – Aivean

0

別のアプローチは、我々はその後、残りを第1のヘッドと同一の項目にリストを二分し、

def encode(xs: List[Symbol]): List[(Int,Symbol)] = xs match { 
    case Nil => Nil 
    case x :: xss => val (g,rest) = xs.span(_ == x) 
        (g.size,g.head) +: encode(rest) 
} 

関連する問題