如何用Scala从文本文件聚合单词元音组合并统计出现次数
解决Spark/Scala聚合单词元音组合并统计次数的问题
嘿,作为Spark/Scala新手能写到这一步已经很棒啦!我来帮你把剩下的逻辑补全,一步步实现你想要的功能。
第一步:确认你的isVowel函数
首先确保你的元音判断函数能正确识别大小写元音,比如:
def isVowel(c: Char): Boolean = { val vowels = Set('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U') vowels.contains(c) }
第二步:提取单词中的连续元音组合
我们需要一个函数,把每个单词拆分成连续的元音序列(比如"file"里的"ei"是连续元音,要作为一个组合),过滤掉非元音的部分:
def extractVowelGroups(word: String): List[String] = { // 遍历单词字符,将连续的元音/非元音分组 val groupedChars = word.foldLeft(List.empty[List[Char]]) { (acc, c) => acc match { case Nil => if (isVowel(c)) List(List(c)) else List(List()) case head :: tail => // 当前字符和组内首字符类型相同(都是元音/都不是),就加入当前组 if (isVowel(c) == isVowel(head.head)) (head :+ c) :: tail // 类型不同,新建一个组 else List(c) :: head :: tail } } // 反转分组顺序,过滤掉非元音组,转成小写字符串(统一大小写) groupedChars.reverse .filter(group => group.nonEmpty && isVowel(group.head)) .map(_.mkString.toLowerCase) }
第三步:整合完整流程(从你的现有代码扩展)
把上面的函数和你已有的代码结合,加上标点处理(避免标点干扰),最终完成统计:
// 读取文件 val wordsFile = sc.textFile("test.txt") // 拆分单词,清理标点,过滤空字符串 val cleanWords = wordsFile .flatMap(line => line.split(" ")) .map(word => word.replaceAll("[^a-zA-Z]", "")) // 移除非字母字符 .filter(_.nonEmpty) // 过滤拆分后可能出现的空字符串 // 提取元音组合并统计次数 val vowelGroupCounts = cleanWords .flatMap(extractVowelGroups) // 每个单词提取所有元音组合,扁平化 .map(group => (group, 1)) // 转成(key, 1)的键值对 .reduceByKey(_ + _) // 按key聚合,累加次数 // 查看结果 vowelGroupCounts.collect().foreach(println)
示例测试
对于文本This is a text file.,运行后会输出:
(i,2) (a,1) (e,1) (ei,1)
额外说明
- 我们把元音组合转成小写,是为了避免
A和a被统计成不同的组合,如果你需要区分大小写,可以去掉.toLowerCase。 - 清理标点的步骤很重要,不然像
file.里的句号会干扰字符判断,导致提取错误。
内容的提问来源于stack exchange,提问作者zach
相关产品推荐
相关产品推荐

