文件读写-全文单词统计 单词拆分与频次统计(2)

37 阅读3分钟

1. 核心思路分析

  • 步骤 1:将完整文本按非字符分隔符拆分为独立单词;

  • 步骤 2:创建可变 Map,以 “单词” 为 Key、“出现次数” 为 Value;

  • 步骤 3:遍历所有单词,更新 Map 中的计数:

    • 若单词已在 Map 中,对应 Value +1;
    • 若单词未在 Map 中,新增 Key 并设置 Value = 1。

2. 单词统计核心代码

// 导入可变Map(Scala默认Map为不可变)
import scala.collection.mutable

// 承接上一步读取的content,拆分单词(\W+ 匹配所有非字母数字字符)
val words = content.split("\W+")

// 初始化空的可变Map,用于存储单词计数
val wordCountMap = mutable.Map[String, Int]()

// 遍历单词数组,更新计数
for (word <- words) {
  // 忽略空字符串(拆分可能产生)
  if (word.nonEmpty) {
    wordCountMap(word) = wordCountMap.getOrElse(word, 0) + 1
  }
}

// 打印原始统计结果(验证)
println("\n原始单词统计结果:")
wordCountMap.foreach { case (word, count) =>
  println(s"$word: $count")
}

3. 对统计结果排序

将 Map 转换为 Seq(序列),通过sortBy指定排序维度,支持升序 / 降序。

排序代码示例

// 按出现次数升序排序(_._2 表示取元组的第二个元素,即计数)
val sortedByCountAsc = wordCountMap.toSeq.sortBy(_._2)

// 按出现次数降序排序(加reverse)
val sortedByCountDesc = wordCountMap.toSeq.sortBy(_._2).reverse

// 打印降序排序结果
println("\n按出现次数降序排序:")
sortedByCountDesc.foreach { case (word, count) =>
  println(s"$word: $count")
}

4. 将结果写入文件

Scala 可复用 Java 的PrintWriter工具实现文件写入,步骤为:创建 Writer 对象 → 写入内容 → 关闭 Writer(释放资源)。

完整写入代码示例

// 导入文件写入所需的包
import java.io.PrintWriter

// 定义写入文件的方法
def writeResultToFile(sortedData: Seq[(String, Int)], outputPath: String): Unit = {
  // 创建PrintWriter对象,指定输出文件路径
  val writer = new PrintWriter(outputPath)
  
  try {
    // 写入文件头
    writer.write("单词统计结果(按出现次数降序)\n")
    writer.write("=============================\n")
    
    // 遍历排序后的结果,逐行写入
    sortedData.foreach { case (word, count) =>
      writer.write(s"$word: $count\n")
    }
    
    println(s"\n统计结果已成功写入:$outputPath")
  } catch {
    // 捕获异常,避免程序崩溃
    case ex: Exception => println(s"写入文件失败:${ex.getMessage}")
  } finally {
    // 无论是否异常,都关闭Writer
    writer.close()
  }
}

// 调用方法,将降序结果写入output.txt
writeResultToFile(sortedByCountDesc, "output.txt")

5. 完整整合代码(可直接运行)

import scala.io.Source
import scala.collection.mutable
import java.io.PrintWriter

object WordCountApp {
  def main(args: Array[String]): Unit = {
    // 步骤1:读取文件内容
    val content = Source.fromFile("example.txt").mkString
    println("文件原始内容:\n" + content)

    // 步骤2:拆分单词并统计
    val words = content.split("\W+")
    val wordCountMap = mutable.Map[String, Int]()
    for (word <- words if word.nonEmpty) {
      wordCountMap(word) = wordCountMap.getOrElse(word, 0) + 1
    }

    // 步骤3:按出现次数降序排序
    val sortedResult = wordCountMap.toSeq.sortBy(_._2).reverse

    // 步骤4:写入文件
    val writer = new PrintWriter("output.txt")
    try {
      writer.write("单词统计结果(降序)\n")
      sortedResult.foreach { case (word, count) =>
        writer.write(s"$word: $count\n")
      }
    } catch {
      case ex: Exception => println(s"错误:${ex.getMessage}")
    } finally {
      writer.close()
    }

    // 控制台输出最终结果
    println("\n最终统计结果:")
    sortedResult.foreach { case (word, count) =>
      println(s"$word: $count")
    }
  }
}

关键知识点说明

  1. \W+:正则表达式,匹配所有非字母、数字、下划线的字符(可拆分英文单词);
  2. getOrElse(word, 0):简化 Map 计数逻辑,若 Key 不存在则返回默认值 0;
  3. mutable.Map:Scala 默认 Map 为不可变,统计时需使用可变 Map;
  4. PrintWriter:写入文件时需手动关闭,建议放在finally块中确保执行。

运行说明

  1. 在项目根目录创建example.txt,写入任意英文文本;
  2. 复制上述代码到 Scala IDE(如 IntelliJ)或在线 Scala 运行环境;
  3. 运行代码后,会生成output.txt文件,包含排序后的单词统计结果。