我是 Scala 的新手,非常感谢任何帮助(到处寻找并花了最后 8 个小时试图解决这个问题)
目前我有
def apply(file: String) : Iterator[String] = {
scala.io.Source.fromFile(file).getLines().map(_.toLowerCase)
}
还有
def groupFreq[A,B](xs: Iterator[A], f: A => B): HashMap[B, Int] = {
var freqMap = new HashMap[B, Int]
for (x <- xs) freqMap = freqMap + ( f(x) -> ( freqMap.getOrElse( f(x) , 0 ) +1 ) )
freqMap
}
apply 只获取我们传入的单词文件。
GroupFreq 采用 xs: Iterator[A] 和一个将 A 值转换为其 B 组的分组函数 f。 该函数返回一个 HashMap,它为每个 B 组计算落入该组的 A 值的数量。
我使用这两个函数来帮助我使用 charFreq,该函数同时使用 apply 和 groupFreq 传回一个 HashMap,该 HashMap 计算 Char 在整个文件中出现的次数。如果 char 没有出现在文件中的任何地方,那么它应该没有映射。
def charFreq(file: String): HashMap[Char, Int] =
{
var it = Iterator[Char]()
val words = apply(file)
for {
xs<-words
} yield { it = it ++ xs.toIterator }
val chars = it
val grouper = (x: Char) => x
groupFreq(chars, grouper)
}
我的解决方案编译和应用并且 groupFreq 按预期工作,但是当我运行 charFreq 时,它说
charFreq threw an exception: java.util.NoSuchElementException: key not found: d
我相信我做错了什么,很可能是我的 for 循环和 yield,但我已经多次检查逻辑,但我不明白为什么它不起作用。
Google 和 StackOverflow 推荐了平面图,但我也无法使用它。
如有任何帮助,我们将不胜感激。请记住,这是一个设置了骨架方法的类作业,所以我无法更改应用、groupFreq 和 charFreq 的设置方式,我只能操纵我尝试过的主体。
最佳答案
我无法用一些随机的字符串文本文件重现您的错误。我怀疑它发生在 groupFreq()
的早期迭代中,没有 getOrElse()
类型测试。
但是,当运行您的代码时,我最终得到一个来自对 charFreq()
调用的空映射。您是正确的, charFreq() 中的循环/ yield 是有问题的。当您在 for
前面放置一个 val l =
并在 IDE 中检查该 l
应该属于的值时,会更容易看到输入 Iterator[Unit]
。
for
循环不需要vars
。 for
循环与 C 风格的 for 循环不同,它等效于对其元素调用 flatMap/map(尽管其他人可以比我更好地表达这一点)。 yield 正在为您连接到某些东西(由您在其中采取的步骤定义)。
这里有两种方法可以为您调用 groupFreq()
获取 Iterator[Char]
:
1> 删除不必要的 var it
并直接用 for 理解循环填充 chars
:
val chars = for {
xs<-words
i<-xs.toIterator
} yield { i }
2> 直接在words
val 上调用flatMap
:
val chars = words.flatMap( s => s )
关于java - Scala HashMap 抛出键未找到异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22288229/