java计算字符串中的二元数

时间:2019-03-15 08:53:45

标签: java

我有以下方法可以创建输入的二元组。我需要计算二元组的数量以计算每次出现的概率。

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

先谢谢了。

3 个答案:

答案 0 :(得分:2)

第一个人可以收集每个二元组的计数:

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,可以维持插入地图的顺序。 作为排序顺序,我首先选择了最常出现的频率,然后选择了二字形文字。

我将分母立即加倍,以便进行浮点除法而不是整数除法。

尽管流符号带有苛刻的语法,但它非常紧凑。

答案 1 :(得分:0)

这是您要找的吗?

public static String sortCountBigrams(ArrayList<String> bigrams) {
    String outputResult = "";
    Collections.sort(bigrams);
    int size = bigrams.size(); //use size to get the total no of elements
    String curr = bigrams.get(0);
    int counter = 1;
    for (String next : bigrams) {
        if (next.equals(curr)) {
            counter++;
        } else {
            outputResult += curr + " " + (Double.toString(counter))/size + " "; //divide by size here 
            counter = 1;
            curr = next;
        }
    }
    return outputResult; 
}

答案 2 :(得分:0)

Map(在此处使用SortedMap)中,创建一个TreeMap,其中键是二元组,值是它们的相应频率。

然后计算所有频率的总和。

最后,浏览地图键(字母组合图)并计算其概率(频率/总和)

public static String sortCountBigrams(List<String> inputList) {
    Map<String, Integer> bigramsAndFrequencies = new TreeMap<>();

    // Make the Map and calculate the sum of frequencies
    int sum = 0;
    int frequency;
    String bigram;
    for(int i=0; i<inputList.size(); i = i+2) {
        bigram = inputList.get(i);
        frequency = Integer.valueOf(inputList.get(i+1));
        bigramsAndFrequencies.put(bigram, frequency);
        sum += frequency;
    }

    System.out.println("sum = " + sum);
    System.out.println("bigramsAndFrequencies = " + bigramsAndFrequencies);

    // Build the output String
    StringBuilder sb = new StringBuilder();
    boolean first = true;
    for(String b : bigramsAndFrequencies.keySet()) {
        if(!first) {
            sb.append(" ");
        }
        first = false;
        sb.append(b)
          .append(" ");
          .append((double)bigramsAndFrequencies.get(b) / (double)(sum));
    }

    System.out.println(sb.toString());

    return sb.toString();
}

输出

sum = 720
bigramsAndFrequencies = {af=22, ag=22, ah=7, ai=53, aj=74, ak=1, al=384, am=157}
af 0.030555555555555555 ag 0.030555555555555555 ah 0.009722222222222222 ai 0.07361111111111111 aj 0.10277777777777777 ak 0.001388888888888889 al 0.5333333333333333 am 0.21805555555555556

sb.append(b)
  .append(" ")
  .append(bigramsAndFrequencies.get(b))
  .append("/")
  .append(sum);

如果需要此输出格式:

af 22/720 ag 22/720 ah 7/720 ai 53/720 aj 74/720 ak 1/720 al 384/720 am 157/720