带有 Tailrec 函数的 Scala 模式匹配
Scala Pattern Matching with Tailrec function
我有以下函数执行 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(<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.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
不是 List
。 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
String
。它被自动解释为 Seq[Char]
.
我有以下函数执行 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(<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.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
不是 List
。 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
String
。它被自动解释为 Seq[Char]
.