基于Tailrec函数的Scala模式匹配

基于Tailrec函数的Scala模式匹配,scala,tail-recursion,Scala,Tail Recursion,我有以下函数,它执行Tailrec并尝试对给定字符串进行字符计数: @scala.annotation.tailrec def letterCount(remaining: Seq[Char], acc: Map[Char, Int]): Map[Char, Int] = remaining match { case Nil => acc case x :: Nil => acc ++ Map(x -> 1) case x :: xs =>

我有以下函数,它执行Tailrec并尝试对给定字符串进行字符计数:

  @scala.annotation.tailrec
  def letterCount(remaining: Seq[Char], acc: Map[Char, Int]): Map[Char, Int] = remaining match {
    case Nil => acc
    case x :: Nil => acc ++ Map(x -> 1)
    case x :: xs =>
      letterCount(xs.filter(_ == x), acc ++ Map(x -> xs.count(_ == x)))
  }

  letterCount("aabbccd".toSeq, Map.empty)
出于某种奇怪的原因,它失败并出现匹配错误:

scala.MatchError: aabbccd (of class scala.collection.immutable.WrappedString)
    at $line87.$read$$iw$$iw$.letterCount(<pastie>:14)
    at $line87.$read$$iw$$iw$.liftedTree1$1(<pastie>:23)
    at $line87.$read$$iw$$iw$.<init>(<pastie>:22)
    at $line87.$read$$iw$$iw$.<clinit>(<pastie>)
    at $line87.$eval$.$print$lzycompute(<pastie>:7)
    at $line87.$eval$.$print(<pastie>:6)
    at $line87.$eval.$print(<pastie>)
scala.MatchError:aabbccd(属于scala.collection.immutable.WrappedString类)
在$line87.$read$$iw$$iw$.letterCount(:14)
在$line87.$read$$iw$$iw$.liftedTree1$1(:23)
在$line87.$read$$iw$$iw$。(:22)
在$line87.$read$$iw$$iw$。()
在$line87.$eval$.$print$lzycompute(:7)
在$line87.$eval$.$print处(:6)
在$line87.$eval.$print()处
我无法找出问题所在!有什么想法吗?

在这里它起作用了:

  @scala.annotation.tailrec
  def letterCount(original: List[Char], remaining: List[Char], acc: Map[Char, Int]): Map[Char, Int] = remaining match {
    case Nil => acc
    case x :: Nil => acc ++ Map(x -> 1)
    case x :: xs =>
      letterCount(original, xs.filter(_ != x), acc ++ Map(x -> original.count(_ == x)))
  }
  letterCount("aabbccd".toList, "aabbccd".toList, Map.empty)
或者,foldLeft也可以这样工作:

"aabbccd".foldLeft[Map[Char,Int]](Map.empty)((map, c) => map + (c -> (map.getOrElse(c, 0) + 1)))
它在这里工作:

  @scala.annotation.tailrec
  def letterCount(original: List[Char], remaining: List[Char], acc: Map[Char, Int]): Map[Char, Int] = remaining match {
    case Nil => acc
    case x :: Nil => acc ++ Map(x -> 1)
    case x :: xs =>
      letterCount(original, xs.filter(_ != x), acc ++ Map(x -> original.count(_ == x)))
  }
  letterCount("aabbccd".toList, "aabbccd".toList, Map.empty)
或者,foldLeft也可以这样工作:

"aabbccd".foldLeft[Map[Char,Int]](Map.empty)((map, c) => map + (c -> (map.getOrElse(c, 0) + 1)))

如评论中所述,
Seq
不是
列表
Seq
没有
Nil
元素,也没有
方法

如果您想继续使用
Seq[Char]
,您可以这样做

@scala.annotation.tailrec
def letterCount(remaining: Seq[Char], acc: Map[Char, Int]): Map[Char, Int] = remaining match {
  case Seq() => acc
  case x +: xs =>
    letterCount(xs.filter(_ != x), acc ++ Map(x -> (xs.count(_ == x)+1)))
}

letterCount("aabbccd", Map.empty)

请注意,您不必
.toSeq
字符串。它被自动解释为
Seq[Char]

如注释中所述,
Seq
不是
列表
Seq
没有
Nil
元素,也没有
方法

如果您想继续使用
Seq[Char]
,您可以这样做

@scala.annotation.tailrec
def letterCount(remaining: Seq[Char], acc: Map[Char, Int]): Map[Char, Int] = remaining match {
  case Seq() => acc
  case x +: xs =>
    letterCount(xs.filter(_ != x), acc ++ Map(x -> (xs.count(_ == x)+1)))
}

letterCount("aabbccd", Map.empty)

请注意,您不必
.toSeq
字符串。它被自动解释为
Seq[Char]

a
Seq
不是
列表
letterCount(“aabbccd.toList,Map.empty”)
工作(从不会抛出的意义上讲),但它有一些逻辑问题。
Seq
不是
列表
letterCount(“aabbccd.toList,Map.empty)
工作(在这个意义上,它不会抛出),但它有一些逻辑问题。