计算map reduce中所有字母出现的概率



我正在尝试使用Map-reduce程序计算文件中每个字母出现的概率。

我正在使用下面的map-reduce框架。1个映射器来映射所有字符,For ex ('a',1)。1个组合器来计算每个字符出现的总数。1个减速器计算平均值。

但是,我无法在reducer中计算平均值。因此,我添加了一个虚拟字符,每当映射器映射一个新字符时,它将被写入一次。

这个虚拟字符表示字符总数,我不知道如何在reducer中访问相同的值并将所有其他值除以总数。

例如,以下是组合器的输出。

# 10
a 2
b 2
c 2
d 4

我尝试了1个减速器,它没有输出。

我特别需要知道必须在reducer中写入的逻辑。

public void reduce(Text key, Iterable<DoubleWritable> values, Context context)
throws IOException, InterruptedException {
int wordCount = 0;
double total = 1;
System.out.println("In Reducer now!");
double avg = 0;
total = values.iterator().next().get();
avg = values.get() / total;
context.write(key, new DoubleWritable(avg));
}

上面的代码没有在输出中写入任何内容。

映射器

public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String s = value.toString();
char[] arrayofChar = s.toCharArray();
for (char ch : arrayofChar) {
System.out.print(ch);
if (Character.isLetter(ch)) {
context.write(new Text(String.valueOf(ch)), new DoubleWritable(1));
context.write(new Text("#"), new DoubleWritable(1));
}
}
}

组合器

public void reduce(Text key, Iterable<DoubleWritable> values, Context context)
throws IOException, InterruptedException {
double total = 0;
System.out.println("In Combiner now!");
for (DoubleWritable value : values) {
total += value.get();
}
context.write(key, new DoubleWritable(total));
}

为了整理,我写了一个单独的消费者:

public class Test {
public static void main(String[] arg) throws Exception{
String s= "aabccdaaab"; 
Averager av = s.chars().collect(Averager::new,Averager::accept, Averager::combine);
System.out.println(av.averages());
}
}
class Averager implements IntConsumer  {
private int count = 0;
private Map<Character,Integer> data = new HashMap<>();

public  Map<Character, Double>averages() {
Map<Character, Double> result = new HashMap<>();
for(Character c : data.keySet()) {
double d = (double)data.get(c)/count;
result.put(c,d);
}
return result;
}

public void accept(int c) { 
Character cc = new Character((char)c);
count++;
if(data.containsKey(cc)) {
int i = data.get(cc);
i++;
data.put(cc, i);
} else {
data.put(cc, 1);
}
}
public void combine(Averager other) {
for(Character c : data.keySet()) {
if(other.data.containsKey(c)) {
int sum = data.get(c) + other.data.get(c);
other.data.put(c, sum);
} else {
other.data.put(c, data.get(c));
}
}
data = other.data;
}
}

输出:

{a=0.5, b=0.2, c=0.2, d=0.1}

相关内容

  • 没有找到相关文章

最新更新