spark 實現共同好友查找

共同好友:求大量集合的兩兩交集
目標:令U爲包含所有用戶的一個集合:{U1,U2,...,Un},我們的目標是爲每個(Ui,Uj)對(i!=j)找出共同好友。
前提:好友關係是雙向的

輸入:<person><,><friend1>< ><friend2>< >...<friendN>

100,200 300 400 500 600
200,100 300 400
300,100 200 400 500
400,100 200 300
500,100,300

600,100

把每個人的好友,兩兩配對形成新的集合 比如第一行進行map以後爲

(100,((200,300),(200,400),(200,500),(200,600),(300,400),

(300,500),(300,600),(400,500),(400,500),(500,600))

然後順着這個思路用flatMapValues 將所有的values拆分,然後進行reduceByKey 可以得出每一對的共同好友

值得注意的事,這裏每一組的好友都是按照數字順序,所以分組不需要對其排序,實際情況下可以先對每個人的好友

進行排序,避免重複

以下是實現代碼

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import scala.collection.mutable.ArrayBuffer


object CommonFriends {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setAppName("Friends").setMaster("local")
    val sc =new SparkContext(conf)
    //讀取文件
    val rddFile=sc.textFile("/input/friends.txt")
    //按行用逗號切分 k,v
    val rddLine=rddFile.map(_.split(","))
    //讓rddLine存入緩存
    rddLine.cache()
    //初始化一個空共同好友集合,將所有人兩兩配對
    val rddEmpty=rddLine.map(x=>("",x(0))).groupByKey().map(x=>{
      val person=x._1
      var paris:Array[Array[String]]=Array()
      val friends= x._2.toArray
      if(friends.length>=2){
        for (i<- 0 until friends.length-1){
          for(j<-i+1 until friends.length){
            val array=Array(friends(i),friends(j))
            paris=paris.++(array::Nil)
          }
        }
      }
      (person,paris)
    })
    //計算有共同好友的好友對  
    val rddSplit=rddLine.map(arr=>{
      //創建好友對數組
      var paris:Array[Array[String]]=Array()
      val person=arr(0)
       //將v 用空格切分爲數組
      val friends=arr(1).split(" ")
        //兩兩配對
      if(friends.length>=2){
        for (i<- 0 until friends.length-1){
          for(j<-i+1 until friends.length){
            val array=Array(friends(i),friends(j))
            paris=paris.++(array::Nil)
          }
        }
      }
      (person,paris)
    })
    //將兩個rdd關聯,如果沒有共同好友會顯示空
    val rddGroups=rddSplit.union(rddEmpty)
    //對paris 進行拆分最爲key ,然後聚合
    val rddResult=rddGroups.flatMapValues(value=>value.map(x=>x)).map(tuple=>((tuple._2(0),tuple._2(1)),tuple._1)).reduceByKey(_+" "+_)
    rddResult.saveAsTextFile("/output13")
    sc.stop()
  }
}

運行結果


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章