0

由于完整代码中前面的 import 语句,此代码中的所有映射都是可变映射。该nGramGetter.getNGrams(...)方法调用返回一个 Map[String, Int]。

  def train(files: Array[java.io.File]): Map[Char, Map[Int, Double]] = {
    val scores = Map[Char, Map[Int, Double]]().withDefault( x => Map[Int, Double]().withDefaultValue(0.0)) 

    for{
      i <- 1 to 4
      nGram <- nGramGetter.getNGrams(files, i).filter( x => (x._1.size == 1 || x._2 > 4) && !hasUnwantedChar(x._1) )
      char <- nGram._1
    } scores(char)(i) += nGram._2
    println(scores.size)
    val nonUnigramTotals = scores.mapValues( x => x.values.reduce(_+_)-x(1) )    

    val unigramTotals = scores.mapValues( x => x(1) )

    scores.map( x => x._1 -> x._2.map( y => y._1 -> (if(y._1 > 1) y._2/unigramTotals(x._1) else (y._2-nonUnigramTotals(x._1))/unigramTotals(x._1)) ) )
  }

scores(char)(i) += nGram._2用一些打印语句(打印每个键中的键、值和单个字符)替换了该行以检查输出,并且方法调用不返回空列表。但是,打印 的大小的行scores正在打印零。我几乎可以肯定我之前已经使用过这种方法来填充频率图,但是这一次,地图总是空的。我已更改withDefaultwithDefaultValue并传入当前函数文字的结果作为参数。我已经尝试过withDefaultwithDefaultValuewith Map[Int, Double](1->0.0,2->0.0,3->0.0,4->0.0)。我有点 Scala 菜鸟,所以也许我只是不了解导致问题的语言。知道有什么问题吗?

4

1 回答 1

2

该方法withDefaultwithDefaultValue没有改变地图。相反,它们只是返回一个默认值。让我们从语句中删除语法糖,看看哪里出错了:

scores(char)(i) += nGram._2
scores(char)(i) = scores(char)(i) + nGram._2
scores.apply(char)(i) = scores.apply(char)(i) + nGram._2
scores.apply(char).update(i, scores.apply(char).apply(i) + nGram._2)

现在,因为scores.apply(char)不存在,所以返回一个默认值Map[Int, Double]().withDefaultValue(0.0),并且映射被修改。不幸的是,它永远不会被分配给scores,因为它没有update调用任何方法。试试下面的代码——它未经测试,但让它工作应该不难:

scores(char) = scores(char) // initializes the map for that key, if it doesn't exist
scores(char)(i) += nGram._2
于 2013-10-14T04:31:43.223 回答