MapReduce--6--求共同好友

来源:互联网 发布:普林数据 编辑:程序博客网 时间:2024/06/05 11:11

MapReduce面试题1--求共同好友


1、数据格式

现有一份数据如下:

A:B,C,D,F,E,OB:A,C,E,KC:F,A,D,ID:A,E,F,LE:B,C,D,M,LF:A,B,C,D,E,O,MG:A,C,D,E,FH:A,C,D,E,OI:A,OJ:B,OK:A,C,DL:D,E,FM:E,F,GO:A,H,I,J,K
数据的格式以“:”分割成两部分,前面是用户,后面是该用户的好友,以

A:B,C,D,F,E,O

为例:B,C,D,E,F,O是用户A的好友


2、题目:求所有用户之间的共同好友


最后的结果格式如下:比如用户A和用户B之间有共同好友:C,E

那么显示的结果是:

A-BC E


3、解题思路分析

根据MapReduce的编程模型的特点,MapReduce编程分为Mapper阶段(任务的拆分)和Reducer阶段(结果的汇总)两个阶段。这两个阶段的业务逻辑,分别编写在Mapper组件的map方法和Reducer组件的reduce方法中。共同点,这两个阶段的业务逻辑方法都是接受key-value对,然后输出key-value对。


所以根据以上结果的格式,可以得知,reducer阶段输出的key-value中的key是A-B,value是C E,

那么value值(C E)怎么得来呢。?根据reduce(key,values,context)方法的特点得知,reduce方法其实接收到的参数是: key相同的一组key-value

也就意味着如果想得到

A-BC E

这样的数据,必先得到如下这样的数据:

A-BCA-BE
以上这种格式的数据的含义是:  C和E 是 A和B 的共同好友
现在再来解析单条数据, 以第一条为例子:

A-BC
表示,C是A用户和B用户的共同好友,  也就是说 C是A的好友, C是B的好友, 所以C 才是A和B的共同好友。
那也就表示,如果能得到以下这样的数据:

CACB
那在MapReduce程序中,就能得到

CA-B
然后倒过来不就是

A-BC
么。 完美。
那么现在的问题(代号q1)就变成怎么得到如下的数据了:
CACB
事实上,这种格式的数据表示: C是A的好友, C是B的好友。
倒过来不就是说: A有好友C,B有好友C么?
现在请看原始数据:
A:B,C,D,F,E,O
这行数据的意思不就是表示A用户有好友B,C,D,F,E,O么?那么拆开就是:

ABACADAFAEAO
这就能得到,q1问题处想要得到的数据了。


4、具体代码实现

具体的代码实现得分成两个MapReduce来实现:
先看第一个MapReduce程序的实现:

package com.ghgj.mazh.mapreduce.exercise.friend;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.Mapper;import org.apache.hadoop.mapreduce.Reducer;import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;public class CommonFriends1MR {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(CommonFriends1MR.class);job.setMapperClass(CommonFriends1MRMapper.class);job.setReducerClass(CommonFriends1MRReducer.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);Path inputPath = new Path("D:\\bigdata\\commonfriends\\input");Path outputPath = new Path("D:\\bigdata\\commonfriends\\output_111");FileSystem fs = FileSystem.get(conf);if (fs.exists(outputPath)) {fs.delete(outputPath, true);}FileInputFormat.setInputPaths(job, inputPath);FileOutputFormat.setOutputPath(job, outputPath);boolean res = job.waitForCompletion(true);System.exit(res ? 0 : 1);}public static class CommonFriends1MRMapper extends Mapper<LongWritable, Text, Text, Text> {@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {String line = value.toString();String[] tokens = line.split(":");String person = tokens[0];String[] friends = tokens[1].split(",");for (String f : friends) {context.write(new Text(f), new Text(person));}}}public static class CommonFriends1MRReducer extends Reducer<Text, Text, Text, Text> {@Overrideprotected void reduce(Text friend, Iterable<Text> persons, Context context)throws IOException, InterruptedException {StringBuffer sb = new StringBuffer();for (Text p : persons) {sb.append(p).append("-");}context.write(friend, new Text(sb.toString()));}}}
该MapReduce输出的结果的格式:

AF-I-O-K-G-D-C-H-B-BE-J-F-A-CB-E-K-A-H-G-F-DH-C-G-F-E-A-K-L-EA-B-L-G-M-F-D-H-FC-M-L-A-D-G-GM-HO-IO-C-JO-KO-B-LD-E-ME-F-OA-H-I-J-F-
这种格式的数据表明:key是value中的任意两个用户的共同好友
比如:

AF-I-O-K-G-D-C-H-B-
表示A是F和I的共同好友,A是F和O的共同好友,A是F和K的共同好友,............



还没有得到最终的结果,所以还需要一个MapReduce程序,来解析第一个MapReduce处理得到的结果数据,以得到最终的结果:
看具体代码实现:

package com.ghgj.mazh.mapreduce.exercise.friend;import java.io.IOException;import java.util.Arrays;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.Mapper;import org.apache.hadoop.mapreduce.Reducer;import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;public class CommonFriends2MR {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();Job job = Job.getInstance(conf);job.setJarByClass(CommonFriends2MR.class);job.setMapperClass(CommonFriends2MRMapper.class);job.setReducerClass(CommonFriends2MRReducer.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);Path inputPath = new Path("D:\\bigdata\\commonfriends\\output_111");Path outputPath = new Path("D:\\bigdata\\commonfriends\\last_output");FileSystem fs = FileSystem.get(conf);if (fs.exists(outputPath)) {fs.delete(outputPath, true);}FileInputFormat.setInputPaths(job, inputPath);FileOutputFormat.setOutputPath(job, outputPath);boolean res = job.waitForCompletion(true);System.exit(res ? 0 : 1);}public static class CommonFriends2MRMapper extends Mapper<LongWritable, Text, Text, Text> {/** * A I-K-C-B-G-F-H-O-D-  * B A-F-J-E-  * C A-E-B-H-F-G-K- */@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {String line = value.toString();String[] tokens = line.split("\t");String friend = tokens[0];String[] persons = tokens[1].split("-");Arrays.sort(persons);for (int i = 0; i < persons.length - 1; i++) {for (int j = i + 1; j < persons.length; j++) {context.write(new Text(persons[i] + "-" + persons[j]), new Text(friend));}}}}public static class CommonFriends2MRReducer extends Reducer<Text, Text, Text, Text> {@Overrideprotected void reduce(Text person_pair, Iterable<Text> friends, Context context) throws IOException, InterruptedException {StringBuffer sb = new StringBuffer();for (Text f : friends) {sb.append(f).append(" ");}context.write(person_pair, new Text(sb.toString()));}}}
第二个MapReduce程序执行得到的结果:

A-BE C A-CD F A-DE F A-EB C D A-FC E O D B A-GE F C D A-HC D E O A-IO A-JO B A-KC D A-LF D E A-MF E B-CA B-DA E B-EC B-FC A E B-GE C A B-HE C A B-IA B-KA C B-LE B-ME B-OA K C-DA F C-ED C-FA D C-GA D F C-HD A C-IA C-KA D C-LD F C-MF C-OI A D-EL D-FA E D-GE A F D-HA E D-IA D-KA D-LE F D-MF E D-OA E-FD M C B E-GC D E-HC D E-JB E-KC D E-LD F-GD C A E F-HA D O E C F-IO A F-JB O F-KD C A F-LE D F-ME F-OA G-HD C E A G-IA G-KD A C G-LD F E G-ME F G-OA H-IO A H-JO H-KA C D H-LD E H-ME H-OA I-JO I-KA I-OA K-LD K-OA L-ME F
以上的数据表示右边的value值就是左边的两个用户的共同好友。


至此,大功告成。ヾ(◍°∇°◍)ノ゙

原创粉丝点击