题目:
A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E,O I:A,O J:B,O K:A,C,D L:D,E,F M:E,F,G O:A,H,I,J,K A-B 就是一对互粉好友对 标准: 最终的所有结果集中必须包含 一组数据 X-Y 必须有 Y-X 那么我们就认为 X-Y 就是最终的结果--- 互粉好友对 A-B B-A A-C A-D D-A B-E
解题思路:
将数据按照从小到大的顺序形成好友对,作为key值,在reduce里面统计key的值,如果key数目为2,即认为是互为好友对。
package practice1; 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.NullWritable; 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; /** * 求互粉好友对 * @author potter */ public class Practice5 { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); // conf.set("fs.defaultFS", "hdfs://potter2:9000"); // System.setProperty("HADOOP_USER_NAME", "potter"); FileSystem fs = FileSystem.get(conf); Job job = Job.getInstance(); job.setJarByClass(Practice5.class); job.setMapperClass(Practice5Mapper.class); job.setReducerClass(Practice5Reducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(NullWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(NullWritable.class); Path input = new Path("D:\\practice\\input5\\work5.txt"); Path output = new Path("D:\\practice\\input5\\output1"); FileInputFormat.setInputPaths(job, input); FileOutputFormat.setOutputPath(job, output); if (fs.exists(output)) { fs.delete(output,true); } boolean isdone = job.waitForCompletion(true); System.exit(isdone ? 0 :1); } public static class Practice5Mapper extends Mapper<LongWritable, Text, Text, NullWritable>{ Text text1 = new Text(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { /** * A:B,C,D,F,E,O * B:A,C,E,K * C:F,A,D,I */ String[] split1 = value.toString().trim().split(":"); String cc = split1[0]; String[] split2 = split1[1].split(","); //用来判断好友对的个数,如果个数等于2,则两个互粉 for (int i = 0; i < split2.length; i++) { String xx = split2[i]; if (cc.compareTo(xx) < 0) { text1.set(cc+"-"+xx); }else { text1.set(xx+"-"+cc); } context.write(text1, NullWritable.get()); } } } public static class Practice5Reducer extends Reducer<Text, NullWritable, Text, NullWritable>{ @Override protected void reduce(Text key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException { //用来记录好友互粉的个数 int count = 0; for(NullWritable dd : values){ count++; } if (count == 2) { context.write(key, NullWritable.get()); } } } }
结果:共16对
A-B A-C A-D A-F A-O B-E C-F D-E D-F D-L E-L E-M F-M H-O I-O J-O