项目需求
一本英文书籍包含成千上万个单词,现在我们需要在大量的单词中,找出相同字母组成的所有单词
数据集
实现分析
观察数据集的数据,可以知道:每行是一个单词word
,这样我们就可以将这个单词转成一个字符数组Array[char]
,然后对这个数组进行排序,再将排序后的字符数组组装成一个新的单词sortWord
作为K,原单词word
作为V,组成<K, V>
的形式;相同的K,他们的V就是相同字母,最后将相同K的V值组合起来,就能得到我们想要的值
代码实现
(1)读取数据文件,生成RDD
val input = "/data/spark-example/anagram/anagram.txt"
val words = sc.textFile(input)
(2)将原单词toCharArray()
转成字符数组,通过sorted
做字符排序,然后mkString("")将排序后的字符数组转成字符串,最后用map
算子组装成(K, V)
的形式
val mapRDD = words.map(word => (word.toCharArray().sorted.mkString(""), word))
(3)通过reduceByKey算子将相同的key的value组合在一起
val reduceRDD = mapRDD.reduceByKey((x, y) => x + "," + y)
(4)通过sortBy
算子将结果按照key进行排序,然后filter
过滤掉未找到相同字母的单词,最后用map
去掉结果的key,输出value值到文件中
val output = "hdfs://oldsix1:9000/data/spark-example/anagram/output4/"
reduceRDD.sortBy(x => x).filter(x => x._2.split(",").length > 1).map(x => x._2).saveAsTextFile(output)
完整代码
import org.apache.spark.{SparkConf, SparkContext}
object SameWordChoose {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("Anagram")
val sc = new SparkContext(conf)
val input = "/data/spark-example/anagram/anagram.txt"
val output = "hdfs://oldsix1:9000/data/spark-example/anagram/output4/"
val words = sc.textFile(input)
val mapRDD = words.map(word => (word.toCharArray().sorted.mkString(""), word))
val reduceRDD = mapRDD.reduceByKey((x, y) => x + "," + y)
reduceRDD.sortBy(x => x).filter(x => x._2.split(",").length > 1).map(x => x._2).saveAsTextFile(output)
sc.stop()
}
}
提交spark任务
将代码打包成jar包并上传,spark-submit
提交任务运行
bin/spark-submit --class cn.oldsix.spark.anagram.SameWordChoose --master local /home/oldsix/app/app-jars/spark/spark-example-0.0.1.jar
任务运行结束,查看hdfs是否生成文件:
将part-00000
文件下载到本地,用文本编辑器打开,查看结果: