曾经遇到一个问题:
有一个文件,其中每一行都记录了存在好友关系的两个人的userId。现要分析此文件,从两两朋友关系的记录中,找出所有的:三人中任意两人互为好友,即三角好友的存在,并打印出来
当时现场没有写出来。最近尝试编写了下,抛去读取文件等基础工作,先实现了三角好友关系查找的实现,编写代码如下:
/**
* Created by leisu on 2018/7/19.
*/
object TriangleFriendsRelationShip {
def main(args: Array[String]) {
//初始化一批数据
val A = "A"
val B = "B"
val C = "C"
val D = "D"
val E = "E"
val F = "F"
val origin = List(A, B) :: List(A, C) :: List(A, D) :: List(B, C) :: List(B, D) :: List(C, D) :: List(C, E) :: List(C, F) :: List(E, F) :: Nil
val oriSet: List[Set[String]] = origin.map(_.toSet)
//调用方法处理
val matchTupelList: List[Tuple2[Set[String], Set[String]]] = findCommonPoint(oriSet)
val resultFinal = findMatchTriangle(oriSet, matchTupelList)
//打印
resultFinal.map(println)
}
/**
* 找出List记录内,任两组数据中有共同顶点的匹配关系,组成新的Tuple 类似Set(A,B)+ Set(A,C) => Tuple2(Set(B,C),Set(A)) 这种结构
* 并最终拼装成新list返回
**/
def findCommonPoint(list: List[Set[String]]): List[Tuple2[Set[String], Set[String]]] = list match {
case headSet :: tail => {
if (tail == Nil) Nil
else {
val lMatch = for (
entrySet <- tail;
item = ((headSet | entrySet) -- (headSet & entrySet), (headSet & entrySet)) //找出合并差
if item._1.size == 2 //只有合并差为2时(即有共同定点时),才筛选出来
) yield item
lMatch ::: findCommonPoint(tail) //递归,此次处理结果与前面处理结果进行合并
}
}
}
/**
* 根据第三条边,找出完整的三角匹配关系
*/
def findMatchTriangle(oriList: List[Set[String]], matchTupelList: List[Tuple2[Set[String], Set[String]]]): List[Set[String]] = {
val resultList = for (entrySet <- oriList;
matchTuple <- matchTupelList;
result = entrySet | matchTuple._2
if (entrySet == matchTuple._1)
) yield result
resultList.distinct //去重
}
}
代码中案例的执行i结果如下:
Set(A, B, C)
Set(A, B, D)
Set(A, C, D)
Set(B, C, D)
Set(C, E, F)
Process finished with exit code 0
根据测试,此结果正确,完成功能