Scala技术咨询:首个数组元素计数与文件特定单词统计
问题2:统计文件中特定单词的出现次数(字段*分隔、行~分隔)
先帮你梳理下现有代码的几个核心问题:
contains("AB").count()是错误写法:contains返回的是Boolean(true/false),布尔值根本没有count()方法,这会直接导致编译报错- 没有维护累加计数器:你没定义一个可以持续累加的变量来统计次数,每次循环的计算结果都没保存
- 缺乏空值和边界处理:分割后可能出现空字符串(比如文件末尾的
~),直接访问数组下标可能触发越界异常
下面是修正后的完整可运行代码,还加了一些实用的优化:
import scala.io.Source object ABWordCounter { def main(args: Array[String]): Unit = { // 替换成你的实际文件路径 val filePath = "./your_input_file.txt" val targetWord = "AB" // 初始化计数器,用var允许累加修改 var matchCount = 0 // 使用use方法自动关闭文件资源,避免资源泄漏 Source.fromFile(filePath).use { bufferedSource => // 读取整个文件内容,按~分割成所有记录,过滤掉空字符串 val allRecords = bufferedSource.mkString.split("\\~").filter(_.trim.nonEmpty) allRecords.foreach { record => // 按*分割字段,同样过滤空字段 val fields = record.split("\\*").filter(_.trim.nonEmpty) // 先判断字段非空,再检查第一个字段是否匹配目标单词 if (fields.nonEmpty && fields(0).trim == targetWord) { matchCount += 1 } } } println(s"单词'$targetWord'一共出现了 $matchCount 次") } }
关键细节说明:
- 资源安全:用
Source.fromFile(...).use确保文件自动关闭,不用手动写close() - 空值过滤:
filter(_.trim.nonEmpty)去掉分割后可能出现的空内容(比如文件开头/结尾的~) - 边界防护:先检查
fields.nonEmpty再访问fields(0),避免格式错误的记录导致数组越界 - 匹配逻辑:这里用的是精确匹配(
==),如果你需要的是"包含AB"而不是完全等于,改成fields(0).trim.contains(targetWord)就行
针对你给出的示例输入:AB*xyz*1234~ CD*mny*769~ MN*bvd*2345~ AB*zar*987~,运行后会输出:单词'AB'一共出现了 2 次,完全符合预期。
如果你的文件很大,不想一次性读取全部内容,也可以用逐行处理的方式(适合大文件,内存更友好):
Source.fromFile(filePath).use { bufferedSource => for (line <- bufferedSource.getLines()) { val records = line.split("\\~").filter(_.trim.nonEmpty) records.foreach { record => val fields = record.split("\\*").filter(_.trim.nonEmpty) if (fields.nonEmpty && fields(0).trim == targetWord) { matchCount += 1 } } } }
内容的提问来源于stack exchange,提问作者Rjj
相关产品推荐
相关产品推荐

