我有以下方法创建输入的二元组。我需要计算二元组的数量以计算每次出现的概率。
public static String sortCountBigrams(ArrayList<String> bigrams) {
String outputResult = "";
Collections.sort(bigrams);
String curr = bigrams.get(0);
int counter = 1;
for (String next : bigrams) {
if (next.equals(curr)) {
counter++;
} else {
outputResult += curr + " " + Double.toString(counter) + " ";
counter = 1;
curr = next;
}
}
return outputResult;
}
这是bigram的示例输出,如下所示:
af 22 ag 22 ah 7 ai 53 aj 74 ak 1 al 384 am 157
我需要将计算(如下)添加到方法中,java库中是否有一个函数可以执行此操作,而bigram中的元素数不是常数。
af 22/8 ag 22/8 ah 7/8 ai 53/8 aj 74/8 ak 1/8 al 384/8 am 157/8
提前致谢。
最佳答案
拳头可以收集每个二元组的计数:
Map<String, Long> counts = bigrams().stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting());
double denominator = counts.size(); // Really not bigrams.size()?
根据要求,我将分母设置为不同的双字母组的数量,而不是所有双字母组的数量(这将给出频率表)。
Map<String, Double> results = new LinkedHashMap<>();
counts.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed()
.thenComparing(Map.Entry.<String, Long>comparingByKey()))
.forEachOrdered(e -> results.put(e.getKey(), e.getValue() / denominator));
System.out.println(results);
通过使用LinkedHashMap,可以维持插入地图的顺序。
作为排序顺序,我首先选择了最常出现的内容,然后选择了二元组文字。
我立即使分母加倍,以便进行浮点除法而不是整数除法。
尽管流符号带有苛刻的语法,但它非常紧凑。