1、题目描述:
在数学中,集合 X 上的二元关系 R 的传递闭包指的是包含 R 的 X 上的最小的传递关系,记作 t®。 例如,假设集合 X 为人的集合 {a,b,c},二元关系 R 为父子关系 {<a,b>,<b,c>}, 其中 <a,b> 和 <b,c> 分别表示a是b的父亲以及b是c的父亲,则 t® 应为祖宗-后代关系 {<a,b>,<b,c>,<a,c>}。 当前,社保局拿到了一份名单,该名单给出了子女-父母的关系。 社保局想要从该名单中分析出名单中包含的子女-祖父母、外祖父母关系。 然而,名单很庞大,如果手工分析可能需要几个小时,于是社保局希望你能帮忙编写程序自动地进行分析。
输入格式:
child parent
Jack Philip
Jack Jesse
Philip Terry
Philip Alma
Jesse Anna
Jesse John
输入保存在文本中,文本的第一行为关系标识,其余行为子女和父母的对应关系。 以上述示例为例,Jack Philip表示Jack与Philip之间存在着子女-父母的关系。
输出格式:
(Jack,[Anna, John, Terry, Alma])
输出保存在文本中,每行的第一个名字代表子女,后面跟随祖父母、外祖父母共四个名字,名字之间使用空格隔开。 需要注意的是,由于输入数据可能缺失部分记录,对于无法分析出祖父母、外祖父母共四人的孙子女,社保局要求不展示在输出结果中。 以上述示例为例,(Jack,[Anna, John, Terry, Alma])表示Jack与Terry、Alma、Anna、John之间存在着孙子女-祖父母(或外祖父母)关系。
在 DSPPCode.spark.transitive_closure.impl 中创建 TransitiveClosureImpl, 继承TransitiveClosuresImpl, 实现抽象方法
2、代码
TransitiveClosuresImpl.java
package DSPPCode.spark.transitive_closures.impl;
import DSPPCode.spark.transitive_closures.question.TransitiveClosures;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;
public class TransitiveClosuresImpl extends TransitiveClosures {
@Override
protected JavaPairRDD<String, Iterable<String>> transitive(JavaRDD<String> lines) {
JavaPairRDD<String, String> childParentRdd = lines.mapToPair(
new PairFunction<String, String, String>() {
@Override
public Tuple2<String, String> call(String s) throws Exception {
String[] tokens = s.split(" ");
String child = tokens[0];
String parent = tokens[1];
return new Tuple2<>(child, parent);
}
});
JavaPairRDD<String, String> parentChildRdd = lines.mapToPair(
new PairFunction<String, String, String>() {
@Override
public Tuple2<String, String> call(String s) throws Exception {
String[] tokens = s.split(" ");
String child = tokens[0];
String parent = tokens[1];
return new Tuple2<>(parent, child);
}
});
JavaPairRDD<String, Tuple2<String, String>> temp1 = parentChildRdd.join(childParentRdd);
JavaPairRDD<String, String> temp2 = temp1.values().mapToPair((Tuple2<String, String> t) -> new Tuple2<>(t._1, t._2));
JavaPairRDD<String, Iterable<String>> res = temp2.groupByKey();
return res.filter((Tuple2<String, Iterable<String>> t) -> (t._2).toString().split(",").length == 4);
}
}