2016-04-14 33 views
0

Özyineleme kullanarak sorunu 13 here'dan çözmeye çalışıyorum, ancak bir hata alıyorum (anlamadığım).Yinelenen öğeleri sayma listesine dönme

sorundur:

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

Ben tekrarlanan elemanları dönmek ve saymak gerekir listesi verilmiş:

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))

Bu benim kodudur

Bu hata:

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 

Neden böyle oluyor ve bunu nasıl düzeltebiliriz? size adil koleksiyonun uzunluğunu dönecektir-

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, yüklem alıp o yüklemi eşleşecek elemanların sayısını hesaplar:

cevap

1

Hatan oldukça basittir sen count yerine size/length kullandım.

Sadece eğlence için, burada önek/sonek içine koleksiyon keser span kullanan alternatif, şöyledir:

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) } 

Ayrıca kullanarak, kuyruk özyinelemeli şekilde bu işlevi yeniden yazmak için iyi bir fikir olabilir Kuyruk yineleme, scala'da daha verimli olduğu için bir argüman olarak akümülatör elde eder. span kullanarak

+0

, tüm yüklemleri eşleştirip "beden" ile eşdeğer olmamalıdır (_); – ps0604

+0

@ ps0604, aslında, hayır. 'Say''daki öntanımlılık işlevi' T => Bool''dur, bu yüzden muhtemelen saymayı deniyorsunuz (_ => doğru). Bu, 'size', sadece daha az verimli eşdeğer olacaktır. – Aivean

0

başka bir yaklaşım, o gece kalan ilk kafasına benzer öğelerin içine listesini bisect ve

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) 
} 

.