题目描述:
根据给定的关系
child parent
Tom Lucy
Tom Jack
Jone Lucy
Jone Jack
Lucy Mary
Lucy Ben
Jack Alice
Jack Jesse
Terry Alice
Terry Jesse
Philip Terry
Philip Alma
Mark Terry
Mark Alma
Tom Lucy
Tom Jack
Jone Lucy
Jone Jack
Lucy Mary
Lucy Ben
Jack Alice
Jack Jesse
Terry Alice
Terry Jesse
Philip Terry
Philip Alma
Mark Terry
Mark Alma
打印出grandchild和grandparents。例如Lucy是Tom 的母亲,而Mary是lucy的目前,那么mary就是tom的外婆
思路:
可知Tom和Mary的关系的建立在于Lucy,也就是说我们只要建立两个表,都存放child和parents如果一个表1中的child和另一个表2中的parents对应,那就说明那个表1中的parents是表2中的child的grandparents了,同理可得grandchild。
那么对于对应关系而言,我们可以利用reduce中会自动将相同的key放在一起这个特性。通过map我们希望得到(childname,1+childname+parentname),(parentname,2+childname+parentname),这样通过reduce,会将childname和parentname相同的归到一类,1和2表示该value的key是child还是parents,通过这个可以获得1的parents是2的child的grandparents
具体代码:
public class MyMapper extends Mapper<LongWritable, Text, Text, Text> {
public void map(LongWritable ikey, Text ivalue, Context context)
throws IOException, InterruptedException {
String line=ivalue.toString();
StringTokenizer st= new StringTokenizer(line);
String childname=st.nextToken().toString();
String parentname=st.nextToken().toString();
if(childname.compareTo("child" )!=0){
context.write( new Text(parentname),new Text("1"+"+" +childname+"+"+parentname));
context.write( new Text(childname),new Text("2"+"+" +childname+"+"+parentname));
}
}
}
map主要用于格式化输出
public class MyReducer extends Reducer<Text, Text, Text, Text> {
static int time=0;
public void reduce(Text _key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
// process values
if (time==0){
context.write(new Text("grandchild"),new Text("grandparent"));
time++;
}
ArrayList<String> child=new ArrayList<String>();
ArrayList<String> parent=new ArrayList<String>();
for (Text val : values) {
String relation=val.toString();
StringTokenizer st=new StringTokenizer(relation,"+");
int flag=Integer.parseInt(st.nextToken());
String childname=st.nextToken().toString();
String parentname=st.nextToken().toString();
if(flag==1){
child.add(childname);
}else if(flag==2){
parent.add(parentname);
}
}
if(child.size()!=0&&parent.size()!=0){
for(int i=0;i<child.size();i++){
for(int j=0;j<parent.size();j++){
context.write(new Text(child.get(i)),new Text(parent.get(j)));
}
}
}
}
}
而reduce则是对后者的处理,最后一步为笛卡尔积